Add SwiftShader source to repo

Oct 6 code drop from Transgaming
Review URL: https://chromereviews.googleplex.com/3846015
diff --git a/src/LLVM/utils/DSAclean.py b/src/LLVM/utils/DSAclean.py
new file mode 100644
index 0000000..6c43357
--- /dev/null
+++ b/src/LLVM/utils/DSAclean.py
@@ -0,0 +1,32 @@
+#! /usr/bin/python
+
+#changelog: 
+#10/13/2005b: replaced the # in tmp(.#*)* with alphanumeric and _, this will then remove
+#nodes such as %tmp.1.i and %tmp._i.3
+#10/13/2005: exntended to remove variables of the form %tmp(.#)* rather than just 
+#%tmp.#, i.e. it now will remove %tmp.12.3.15 etc, additionally fixed a spelling error in
+#the comments
+#10/12/2005: now it only removes nodes and edges for which the label is %tmp.# rather
+#than removing all lines for which the lable CONTAINS %tmp.#
+import re
+import sys
+if( len(sys.argv) < 3 ):
+	print 'usage is: ./DSAclean <dot_file_to_be_cleaned> <out_put_file>'
+	sys.exit(1)
+#get a file object
+input = open(sys.argv[1], 'r')
+output = open(sys.argv[2], 'w')
+#we'll get this one line at a time...while we could just put the whole thing in a string
+#it would kill old computers
+buffer = input.readline()
+while buffer != '':
+	if re.compile("label(\s*)=(\s*)\"\s%tmp(.\w*)*(\s*)\"").search(buffer):
+		#skip next line, write neither this line nor the next
+		buffer = input.readline()
+	else:
+		#this isn't a tmp Node, we can write it
+		output.write(buffer)
+	#prepare for the next iteration
+	buffer = input.readline()
+input.close()
+output.close()
diff --git a/src/LLVM/utils/DSAextract.py b/src/LLVM/utils/DSAextract.py
new file mode 100644
index 0000000..134e945
--- /dev/null
+++ b/src/LLVM/utils/DSAextract.py
@@ -0,0 +1,111 @@
+#! /usr/bin/python
+
+#this is a script to extract given named nodes from a dot file, with
+#the associated edges.  An edge is kept iff for edge x -> y
+# x and y are both nodes specified to be kept.
+
+#known issues: if a line contains '->' and is not an edge line
+#problems will occur.  If node labels do not begin with
+#Node this also will not work.  Since this is designed to work
+#on DSA dot output and not general dot files this is ok.
+#If you want to use this on other files rename the node labels
+#to Node[.*] with a script or something.  This also relies on
+#the length of a node name being 13 characters (as it is in all
+#DSA dot output files)
+
+#Note that the name of the node can be any substring of the actual
+#name in the dot file.  Thus if you say specify COLLAPSED
+#as a parameter this script will pull out all COLLAPSED
+#nodes in the file
+
+#Specifying escape characters in the name like \n also will not work, 
+#as Python
+#will make it \\n, I'm not really sure how to fix this
+
+#currently the script prints the names it is searching for
+#to STDOUT, so you can check to see if they are what you intend
+
+import re
+import string
+import sys
+
+
+if len(sys.argv) < 3:
+	print 'usage is ./DSAextract <dot_file_to_modify> \
+			<output_file> [list of nodes to extract]'
+
+#open the input file
+input = open(sys.argv[1], 'r')
+
+#construct a set of node names
+node_name_set = set()
+for name in sys.argv[3:]:
+	node_name_set |= set([name])
+
+#construct a list of compiled regular expressions from the 
+#node_name_set
+regexp_list = []
+for name in node_name_set:
+	regexp_list.append(re.compile(name))
+
+#used to see what kind of line we are on
+nodeexp = re.compile('Node')
+#used to check to see if the current line is an edge line
+arrowexp = re.compile('->')
+
+node_set = set()
+
+#read the file one line at a time
+buffer = input.readline()
+while buffer != '':
+	#filter out the unecessary checks on all the edge lines
+	if not arrowexp.search(buffer):
+		#check to see if this is a node we are looking for
+		for regexp in regexp_list:
+			#if this name is for the current node, add the dot variable name
+			#for the node (it will be Node(hex number)) to our set of nodes
+			if regexp.search(buffer):
+				node_set |= set([re.split('\s+',buffer,2)[1]])
+				break
+	buffer = input.readline()
+
+
+#test code
+#print '\n'
+
+print node_name_set
+
+#print node_set
+	
+
+#open the output file
+output = open(sys.argv[2], 'w')
+#start the second pass over the file
+input = open(sys.argv[1], 'r')
+
+buffer = input.readline()
+while buffer != '':
+	#there are three types of lines we are looking for
+	#1) node lines, 2) edge lines 3) support lines (like page size, etc)
+	
+	#is this an edge line?
+	#note that this is no completely robust, if a none edge line
+	#for some reason contains -> it will be missidentified
+	#hand edit the file if this happens
+	if arrowexp.search(buffer):
+		#check to make sure that both nodes are in the node list
+		#if they are print this to output
+		nodes = arrowexp.split(buffer)
+		nodes[0] = string.strip(nodes[0])
+		nodes[1] = string.strip(nodes[1])
+		if nodes[0][:13] in node_set and \
+				nodes[1][:13] in node_set:
+					output.write(buffer)
+	elif nodeexp.search(buffer): #this is a node line
+		node = re.split('\s+', buffer,2)[1]
+		if node in node_set:
+			output.write(buffer)
+	else: #this is a support line
+		output.write(buffer)
+	buffer = input.readline()
+
diff --git a/src/LLVM/utils/FileCheck/CMakeLists.txt b/src/LLVM/utils/FileCheck/CMakeLists.txt
new file mode 100644
index 0000000..8fee03f
--- /dev/null
+++ b/src/LLVM/utils/FileCheck/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_executable(FileCheck
+  FileCheck.cpp
+  )
+
+target_link_libraries(FileCheck LLVMSupport LLVMSystem)
+if( MINGW )
+  target_link_libraries(FileCheck imagehlp psapi)
+endif( MINGW )
+if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD )
+  target_link_libraries(FileCheck pthread)
+endif()
diff --git a/src/LLVM/utils/FileCheck/FileCheck.cpp b/src/LLVM/utils/FileCheck/FileCheck.cpp
new file mode 100644
index 0000000..e7cd713
--- /dev/null
+++ b/src/LLVM/utils/FileCheck/FileCheck.cpp
@@ -0,0 +1,732 @@
+//===- FileCheck.cpp - Check that File's Contents match what is expected --===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// FileCheck does a line-by line check of a file that validates whether it
+// contains the expected content.  This is useful for regression tests etc.
+//
+// This program exits with an error status of 2 on error, exit status of 0 if
+// the file matched the expected contents, and exit status of 1 if it did not
+// contain the expected contents.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Signals.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringMap.h"
+#include <algorithm>
+using namespace llvm;
+
+static cl::opt<std::string>
+CheckFilename(cl::Positional, cl::desc("<check-file>"), cl::Required);
+
+static cl::opt<std::string>
+InputFilename("input-file", cl::desc("File to check (defaults to stdin)"),
+              cl::init("-"), cl::value_desc("filename"));
+
+static cl::opt<std::string>
+CheckPrefix("check-prefix", cl::init("CHECK"),
+            cl::desc("Prefix to use from check file (defaults to 'CHECK')"));
+
+static cl::opt<bool>
+NoCanonicalizeWhiteSpace("strict-whitespace",
+              cl::desc("Do not treat all horizontal whitespace as equivalent"));
+
+//===----------------------------------------------------------------------===//
+// Pattern Handling Code.
+//===----------------------------------------------------------------------===//
+
+class Pattern {
+  SMLoc PatternLoc;
+  
+  /// FixedStr - If non-empty, this pattern is a fixed string match with the
+  /// specified fixed string.
+  StringRef FixedStr;
+  
+  /// RegEx - If non-empty, this is a regex pattern.
+  std::string RegExStr;
+  
+  /// VariableUses - Entries in this vector map to uses of a variable in the
+  /// pattern, e.g. "foo[[bar]]baz".  In this case, the RegExStr will contain
+  /// "foobaz" and we'll get an entry in this vector that tells us to insert the
+  /// value of bar at offset 3.
+  std::vector<std::pair<StringRef, unsigned> > VariableUses;
+  
+  /// VariableDefs - Entries in this vector map to definitions of a variable in
+  /// the pattern, e.g. "foo[[bar:.*]]baz".  In this case, the RegExStr will
+  /// contain "foo(.*)baz" and VariableDefs will contain the pair "bar",1.  The
+  /// index indicates what parenthesized value captures the variable value.
+  std::vector<std::pair<StringRef, unsigned> > VariableDefs;
+  
+public:
+  
+  Pattern() { }
+  
+  bool ParsePattern(StringRef PatternStr, SourceMgr &SM);
+  
+  /// Match - Match the pattern string against the input buffer Buffer.  This
+  /// returns the position that is matched or npos if there is no match.  If
+  /// there is a match, the size of the matched string is returned in MatchLen.
+  ///
+  /// The VariableTable StringMap provides the current values of filecheck
+  /// variables and is updated if this match defines new values.
+  size_t Match(StringRef Buffer, size_t &MatchLen,
+               StringMap<StringRef> &VariableTable) const;
+
+  /// PrintFailureInfo - Print additional information about a failure to match
+  /// involving this pattern.
+  void PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
+                        const StringMap<StringRef> &VariableTable) const;
+
+private:
+  static void AddFixedStringToRegEx(StringRef FixedStr, std::string &TheStr);
+  bool AddRegExToRegEx(StringRef RegExStr, unsigned &CurParen, SourceMgr &SM);
+
+  /// ComputeMatchDistance - Compute an arbitrary estimate for the quality of
+  /// matching this pattern at the start of \arg Buffer; a distance of zero
+  /// should correspond to a perfect match.
+  unsigned ComputeMatchDistance(StringRef Buffer,
+                               const StringMap<StringRef> &VariableTable) const;
+};
+
+
+bool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM) {
+  PatternLoc = SMLoc::getFromPointer(PatternStr.data());
+  
+  // Ignore trailing whitespace.
+  while (!PatternStr.empty() &&
+         (PatternStr.back() == ' ' || PatternStr.back() == '\t'))
+    PatternStr = PatternStr.substr(0, PatternStr.size()-1);
+  
+  // Check that there is something on the line.
+  if (PatternStr.empty()) {
+    SM.PrintMessage(PatternLoc, "found empty check string with prefix '" +
+                    CheckPrefix+":'", "error");
+    return true;
+  }
+  
+  // Check to see if this is a fixed string, or if it has regex pieces.
+  if (PatternStr.size() < 2 ||
+      (PatternStr.find("{{") == StringRef::npos &&
+       PatternStr.find("[[") == StringRef::npos)) {
+    FixedStr = PatternStr;
+    return false;
+  }
+  
+  // Paren value #0 is for the fully matched string.  Any new parenthesized
+  // values add from their.
+  unsigned CurParen = 1;
+  
+  // Otherwise, there is at least one regex piece.  Build up the regex pattern
+  // by escaping scary characters in fixed strings, building up one big regex.
+  while (!PatternStr.empty()) {
+    // RegEx matches.
+    if (PatternStr.size() >= 2 &&
+        PatternStr[0] == '{' && PatternStr[1] == '{') {
+     
+      // Otherwise, this is the start of a regex match.  Scan for the }}.
+      size_t End = PatternStr.find("}}");
+      if (End == StringRef::npos) {
+        SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
+                        "found start of regex string with no end '}}'", "error");
+        return true;
+      }
+      
+      if (AddRegExToRegEx(PatternStr.substr(2, End-2), CurParen, SM))
+        return true;
+      PatternStr = PatternStr.substr(End+2);
+      continue;
+    }
+    
+    // Named RegEx matches.  These are of two forms: [[foo:.*]] which matches .*
+    // (or some other regex) and assigns it to the FileCheck variable 'foo'. The
+    // second form is [[foo]] which is a reference to foo.  The variable name
+    // itself must be of the form "[a-zA-Z_][0-9a-zA-Z_]*", otherwise we reject
+    // it.  This is to catch some common errors.
+    if (PatternStr.size() >= 2 &&
+        PatternStr[0] == '[' && PatternStr[1] == '[') {
+      // Verify that it is terminated properly.
+      size_t End = PatternStr.find("]]");
+      if (End == StringRef::npos) {
+        SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
+                        "invalid named regex reference, no ]] found", "error");
+        return true;
+      }
+      
+      StringRef MatchStr = PatternStr.substr(2, End-2);
+      PatternStr = PatternStr.substr(End+2);
+      
+      // Get the regex name (e.g. "foo").
+      size_t NameEnd = MatchStr.find(':');
+      StringRef Name = MatchStr.substr(0, NameEnd);
+      
+      if (Name.empty()) {
+        SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
+                        "invalid name in named regex: empty name", "error");
+        return true;
+      }
+
+      // Verify that the name is well formed.
+      for (unsigned i = 0, e = Name.size(); i != e; ++i)
+        if (Name[i] != '_' &&
+            (Name[i] < 'a' || Name[i] > 'z') &&
+            (Name[i] < 'A' || Name[i] > 'Z') &&
+            (Name[i] < '0' || Name[i] > '9')) {
+          SM.PrintMessage(SMLoc::getFromPointer(Name.data()+i),
+                          "invalid name in named regex", "error");
+          return true;
+        }
+      
+      // Name can't start with a digit.
+      if (isdigit(Name[0])) {
+        SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
+                        "invalid name in named regex", "error");
+        return true;
+      }
+      
+      // Handle [[foo]].
+      if (NameEnd == StringRef::npos) {
+        VariableUses.push_back(std::make_pair(Name, RegExStr.size()));
+        continue;
+      }
+      
+      // Handle [[foo:.*]].
+      VariableDefs.push_back(std::make_pair(Name, CurParen));
+      RegExStr += '(';
+      ++CurParen;
+      
+      if (AddRegExToRegEx(MatchStr.substr(NameEnd+1), CurParen, SM))
+        return true;
+
+      RegExStr += ')';
+    }
+    
+    // Handle fixed string matches.
+    // Find the end, which is the start of the next regex.
+    size_t FixedMatchEnd = PatternStr.find("{{");
+    FixedMatchEnd = std::min(FixedMatchEnd, PatternStr.find("[["));
+    AddFixedStringToRegEx(PatternStr.substr(0, FixedMatchEnd), RegExStr);
+    PatternStr = PatternStr.substr(FixedMatchEnd);
+    continue;
+  }
+
+  return false;
+}
+
+void Pattern::AddFixedStringToRegEx(StringRef FixedStr, std::string &TheStr) {
+  // Add the characters from FixedStr to the regex, escaping as needed.  This
+  // avoids "leaning toothpicks" in common patterns.
+  for (unsigned i = 0, e = FixedStr.size(); i != e; ++i) {
+    switch (FixedStr[i]) {
+    // These are the special characters matched in "p_ere_exp".
+    case '(':
+    case ')':
+    case '^':
+    case '$':
+    case '|':
+    case '*':
+    case '+':
+    case '?':
+    case '.':
+    case '[':
+    case '\\':
+    case '{':
+      TheStr += '\\';
+      // FALL THROUGH.
+    default:
+      TheStr += FixedStr[i];
+      break;
+    }
+  }
+}
+
+bool Pattern::AddRegExToRegEx(StringRef RegexStr, unsigned &CurParen,
+                              SourceMgr &SM) {
+  Regex R(RegexStr);
+  std::string Error;
+  if (!R.isValid(Error)) {
+    SM.PrintMessage(SMLoc::getFromPointer(RegexStr.data()),
+                    "invalid regex: " + Error, "error");
+    return true;
+  }
+  
+  RegExStr += RegexStr.str();
+  CurParen += R.getNumMatches();
+  return false;
+}
+
+/// Match - Match the pattern string against the input buffer Buffer.  This
+/// returns the position that is matched or npos if there is no match.  If
+/// there is a match, the size of the matched string is returned in MatchLen.
+size_t Pattern::Match(StringRef Buffer, size_t &MatchLen,
+                      StringMap<StringRef> &VariableTable) const {
+  // If this is a fixed string pattern, just match it now.
+  if (!FixedStr.empty()) {
+    MatchLen = FixedStr.size();
+    return Buffer.find(FixedStr);
+  }
+
+  // Regex match.
+  
+  // If there are variable uses, we need to create a temporary string with the
+  // actual value.
+  StringRef RegExToMatch = RegExStr;
+  std::string TmpStr;
+  if (!VariableUses.empty()) {
+    TmpStr = RegExStr;
+    
+    unsigned InsertOffset = 0;
+    for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) {
+      StringMap<StringRef>::iterator it =
+        VariableTable.find(VariableUses[i].first);
+      // If the variable is undefined, return an error.
+      if (it == VariableTable.end())
+        return StringRef::npos;
+
+      // Look up the value and escape it so that we can plop it into the regex.
+      std::string Value;
+      AddFixedStringToRegEx(it->second, Value);
+      
+      // Plop it into the regex at the adjusted offset.
+      TmpStr.insert(TmpStr.begin()+VariableUses[i].second+InsertOffset,
+                    Value.begin(), Value.end());
+      InsertOffset += Value.size();
+    }
+    
+    // Match the newly constructed regex.
+    RegExToMatch = TmpStr;
+  }
+  
+  
+  SmallVector<StringRef, 4> MatchInfo;
+  if (!Regex(RegExToMatch, Regex::Newline).match(Buffer, &MatchInfo))
+    return StringRef::npos;
+  
+  // Successful regex match.
+  assert(!MatchInfo.empty() && "Didn't get any match");
+  StringRef FullMatch = MatchInfo[0];
+  
+  // If this defines any variables, remember their values.
+  for (unsigned i = 0, e = VariableDefs.size(); i != e; ++i) {
+    assert(VariableDefs[i].second < MatchInfo.size() &&
+           "Internal paren error");
+    VariableTable[VariableDefs[i].first] = MatchInfo[VariableDefs[i].second];
+  }
+  
+  MatchLen = FullMatch.size();
+  return FullMatch.data()-Buffer.data();
+}
+
+unsigned Pattern::ComputeMatchDistance(StringRef Buffer,
+                              const StringMap<StringRef> &VariableTable) const {
+  // Just compute the number of matching characters. For regular expressions, we
+  // just compare against the regex itself and hope for the best.
+  //
+  // FIXME: One easy improvement here is have the regex lib generate a single
+  // example regular expression which matches, and use that as the example
+  // string.
+  StringRef ExampleString(FixedStr);
+  if (ExampleString.empty())
+    ExampleString = RegExStr;
+
+  // Only compare up to the first line in the buffer, or the string size.
+  StringRef BufferPrefix = Buffer.substr(0, ExampleString.size());
+  BufferPrefix = BufferPrefix.split('\n').first;
+  return BufferPrefix.edit_distance(ExampleString);
+}
+
+void Pattern::PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
+                               const StringMap<StringRef> &VariableTable) const{
+  // If this was a regular expression using variables, print the current
+  // variable values.
+  if (!VariableUses.empty()) {
+    for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) {
+      StringRef Var = VariableUses[i].first;
+      StringMap<StringRef>::const_iterator it = VariableTable.find(Var);
+      SmallString<256> Msg;
+      raw_svector_ostream OS(Msg);
+
+      // Check for undefined variable references.
+      if (it == VariableTable.end()) {
+        OS << "uses undefined variable \"";
+        OS.write_escaped(Var) << "\"";;
+      } else {
+        OS << "with variable \"";
+        OS.write_escaped(Var) << "\" equal to \"";
+        OS.write_escaped(it->second) << "\"";
+      }
+
+      SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), OS.str(), "note",
+                      /*ShowLine=*/false);
+    }
+  }
+
+  // Attempt to find the closest/best fuzzy match.  Usually an error happens
+  // because some string in the output didn't exactly match. In these cases, we
+  // would like to show the user a best guess at what "should have" matched, to
+  // save them having to actually check the input manually.
+  size_t NumLinesForward = 0;
+  size_t Best = StringRef::npos;
+  double BestQuality = 0;
+
+  // Use an arbitrary 4k limit on how far we will search.
+  for (size_t i = 0, e = std::min(size_t(4096), Buffer.size()); i != e; ++i) {
+    if (Buffer[i] == '\n')
+      ++NumLinesForward;
+
+    // Patterns have leading whitespace stripped, so skip whitespace when
+    // looking for something which looks like a pattern.
+    if (Buffer[i] == ' ' || Buffer[i] == '\t')
+      continue;
+
+    // Compute the "quality" of this match as an arbitrary combination of the
+    // match distance and the number of lines skipped to get to this match.
+    unsigned Distance = ComputeMatchDistance(Buffer.substr(i), VariableTable);
+    double Quality = Distance + (NumLinesForward / 100.);
+
+    if (Quality < BestQuality || Best == StringRef::npos) {
+      Best = i;
+      BestQuality = Quality;
+    }
+  }
+
+  // Print the "possible intended match here" line if we found something
+  // reasonable and not equal to what we showed in the "scanning from here"
+  // line.
+  if (Best && Best != StringRef::npos && BestQuality < 50) {
+      SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + Best),
+                      "possible intended match here", "note");
+
+    // FIXME: If we wanted to be really friendly we would show why the match
+    // failed, as it can be hard to spot simple one character differences.
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Check Strings.
+//===----------------------------------------------------------------------===//
+
+/// CheckString - This is a check that we found in the input file.
+struct CheckString {
+  /// Pat - The pattern to match.
+  Pattern Pat;
+  
+  /// Loc - The location in the match file that the check string was specified.
+  SMLoc Loc;
+  
+  /// IsCheckNext - This is true if this is a CHECK-NEXT: directive (as opposed
+  /// to a CHECK: directive.
+  bool IsCheckNext;
+  
+  /// NotStrings - These are all of the strings that are disallowed from
+  /// occurring between this match string and the previous one (or start of
+  /// file).
+  std::vector<std::pair<SMLoc, Pattern> > NotStrings;
+  
+  CheckString(const Pattern &P, SMLoc L, bool isCheckNext)
+    : Pat(P), Loc(L), IsCheckNext(isCheckNext) {}
+};
+
+/// CanonicalizeInputFile - Remove duplicate horizontal space from the specified
+/// memory buffer, free it, and return a new one.
+static MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB) {
+  SmallString<128> NewFile;
+  NewFile.reserve(MB->getBufferSize());
+  
+  for (const char *Ptr = MB->getBufferStart(), *End = MB->getBufferEnd();
+       Ptr != End; ++Ptr) {
+    // If C is not a horizontal whitespace, skip it.
+    if (*Ptr != ' ' && *Ptr != '\t') {
+      NewFile.push_back(*Ptr);
+      continue;
+    }
+    
+    // Otherwise, add one space and advance over neighboring space.
+    NewFile.push_back(' ');
+    while (Ptr+1 != End &&
+           (Ptr[1] == ' ' || Ptr[1] == '\t'))
+      ++Ptr;
+  }
+  
+  // Free the old buffer and return a new one.
+  MemoryBuffer *MB2 =
+    MemoryBuffer::getMemBufferCopy(NewFile.str(), MB->getBufferIdentifier());
+  
+  delete MB;
+  return MB2;
+}
+
+
+/// ReadCheckFile - Read the check file, which specifies the sequence of
+/// expected strings.  The strings are added to the CheckStrings vector.
+static bool ReadCheckFile(SourceMgr &SM,
+                          std::vector<CheckString> &CheckStrings) {
+  // Open the check file, and tell SourceMgr about it.
+  std::string ErrorStr;
+  MemoryBuffer *F =
+    MemoryBuffer::getFileOrSTDIN(CheckFilename.c_str(), &ErrorStr);
+  if (F == 0) {
+    errs() << "Could not open check file '" << CheckFilename << "': " 
+           << ErrorStr << '\n';
+    return true;
+  }
+  
+  // If we want to canonicalize whitespace, strip excess whitespace from the
+  // buffer containing the CHECK lines.
+  if (!NoCanonicalizeWhiteSpace)
+    F = CanonicalizeInputFile(F);
+  
+  SM.AddNewSourceBuffer(F, SMLoc());
+
+  // Find all instances of CheckPrefix followed by : in the file.
+  StringRef Buffer = F->getBuffer();
+
+  std::vector<std::pair<SMLoc, Pattern> > NotMatches;
+  
+  while (1) {
+    // See if Prefix occurs in the memory buffer.
+    Buffer = Buffer.substr(Buffer.find(CheckPrefix));
+    
+    // If we didn't find a match, we're done.
+    if (Buffer.empty())
+      break;
+    
+    const char *CheckPrefixStart = Buffer.data();
+    
+    // When we find a check prefix, keep track of whether we find CHECK: or
+    // CHECK-NEXT:
+    bool IsCheckNext = false, IsCheckNot = false;
+    
+    // Verify that the : is present after the prefix.
+    if (Buffer[CheckPrefix.size()] == ':') {
+      Buffer = Buffer.substr(CheckPrefix.size()+1);
+    } else if (Buffer.size() > CheckPrefix.size()+6 &&
+               memcmp(Buffer.data()+CheckPrefix.size(), "-NEXT:", 6) == 0) {
+      Buffer = Buffer.substr(CheckPrefix.size()+7);
+      IsCheckNext = true;
+    } else if (Buffer.size() > CheckPrefix.size()+5 &&
+               memcmp(Buffer.data()+CheckPrefix.size(), "-NOT:", 5) == 0) {
+      Buffer = Buffer.substr(CheckPrefix.size()+6);
+      IsCheckNot = true;
+    } else {
+      Buffer = Buffer.substr(1);
+      continue;
+    }
+    
+    // Okay, we found the prefix, yay.  Remember the rest of the line, but
+    // ignore leading and trailing whitespace.
+    Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));
+    
+    // Scan ahead to the end of line.
+    size_t EOL = Buffer.find_first_of("\n\r");
+
+    // Remember the location of the start of the pattern, for diagnostics.
+    SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());
+
+    // Parse the pattern.
+    Pattern P;
+    if (P.ParsePattern(Buffer.substr(0, EOL), SM))
+      return true;
+    
+    Buffer = Buffer.substr(EOL);
+
+    
+    // Verify that CHECK-NEXT lines have at least one CHECK line before them.
+    if (IsCheckNext && CheckStrings.empty()) {
+      SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart),
+                      "found '"+CheckPrefix+"-NEXT:' without previous '"+
+                      CheckPrefix+ ": line", "error");
+      return true;
+    }
+    
+    // Handle CHECK-NOT.
+    if (IsCheckNot) {
+      NotMatches.push_back(std::make_pair(SMLoc::getFromPointer(Buffer.data()),
+                                          P));
+      continue;
+    }
+    
+    
+    // Okay, add the string we captured to the output vector and move on.
+    CheckStrings.push_back(CheckString(P,
+                                       PatternLoc,
+                                       IsCheckNext));
+    std::swap(NotMatches, CheckStrings.back().NotStrings);
+  }
+  
+  if (CheckStrings.empty()) {
+    errs() << "error: no check strings found with prefix '" << CheckPrefix
+           << ":'\n";
+    return true;
+  }
+  
+  if (!NotMatches.empty()) {
+    errs() << "error: '" << CheckPrefix
+           << "-NOT:' not supported after last check line.\n";
+    return true;
+  }
+  
+  return false;
+}
+
+static void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr,
+                             StringRef Buffer,
+                             StringMap<StringRef> &VariableTable) {
+  // Otherwise, we have an error, emit an error message.
+  SM.PrintMessage(CheckStr.Loc, "expected string not found in input",
+                  "error");
+  
+  // Print the "scanning from here" line.  If the current position is at the
+  // end of a line, advance to the start of the next line.
+  Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r"));
+  
+  SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), "scanning from here",
+                  "note");
+
+  // Allow the pattern to print additional information if desired.
+  CheckStr.Pat.PrintFailureInfo(SM, Buffer, VariableTable);
+}
+
+/// CountNumNewlinesBetween - Count the number of newlines in the specified
+/// range.
+static unsigned CountNumNewlinesBetween(StringRef Range) {
+  unsigned NumNewLines = 0;
+  while (1) {
+    // Scan for newline.
+    Range = Range.substr(Range.find_first_of("\n\r"));
+    if (Range.empty()) return NumNewLines;
+    
+    ++NumNewLines;
+    
+    // Handle \n\r and \r\n as a single newline.
+    if (Range.size() > 1 &&
+        (Range[1] == '\n' || Range[1] == '\r') &&
+        (Range[0] != Range[1]))
+      Range = Range.substr(1);
+    Range = Range.substr(1);
+  }
+}
+
+int main(int argc, char **argv) {
+  sys::PrintStackTraceOnErrorSignal();
+  PrettyStackTraceProgram X(argc, argv);
+  cl::ParseCommandLineOptions(argc, argv);
+
+  SourceMgr SM;
+  
+  // Read the expected strings from the check file.
+  std::vector<CheckString> CheckStrings;
+  if (ReadCheckFile(SM, CheckStrings))
+    return 2;
+
+  // Open the file to check and add it to SourceMgr.
+  std::string ErrorStr;
+  MemoryBuffer *F =
+    MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), &ErrorStr);
+  if (F == 0) {
+    errs() << "Could not open input file '" << InputFilename << "': " 
+           << ErrorStr << '\n';
+    return true;
+  }
+  
+  // Remove duplicate spaces in the input file if requested.
+  if (!NoCanonicalizeWhiteSpace)
+    F = CanonicalizeInputFile(F);
+  
+  SM.AddNewSourceBuffer(F, SMLoc());
+  
+  /// VariableTable - This holds all the current filecheck variables.
+  StringMap<StringRef> VariableTable;
+  
+  // Check that we have all of the expected strings, in order, in the input
+  // file.
+  StringRef Buffer = F->getBuffer();
+  
+  const char *LastMatch = Buffer.data();
+  
+  for (unsigned StrNo = 0, e = CheckStrings.size(); StrNo != e; ++StrNo) {
+    const CheckString &CheckStr = CheckStrings[StrNo];
+    
+    StringRef SearchFrom = Buffer;
+    
+    // Find StrNo in the file.
+    size_t MatchLen = 0;
+    Buffer = Buffer.substr(CheckStr.Pat.Match(Buffer, MatchLen, VariableTable));
+    
+    // If we didn't find a match, reject the input.
+    if (Buffer.empty()) {
+      PrintCheckFailed(SM, CheckStr, SearchFrom, VariableTable);
+      return 1;
+    }
+
+    StringRef SkippedRegion(LastMatch, Buffer.data()-LastMatch);
+
+    // If this check is a "CHECK-NEXT", verify that the previous match was on
+    // the previous line (i.e. that there is one newline between them).
+    if (CheckStr.IsCheckNext) {
+      // Count the number of newlines between the previous match and this one.
+      assert(LastMatch != F->getBufferStart() &&
+             "CHECK-NEXT can't be the first check in a file");
+
+      unsigned NumNewLines = CountNumNewlinesBetween(SkippedRegion);
+      if (NumNewLines == 0) {
+        SM.PrintMessage(CheckStr.Loc,
+                    CheckPrefix+"-NEXT: is on the same line as previous match",
+                        "error");
+        SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
+                        "'next' match was here", "note");
+        SM.PrintMessage(SMLoc::getFromPointer(LastMatch),
+                        "previous match was here", "note");
+        return 1;
+      }
+      
+      if (NumNewLines != 1) {
+        SM.PrintMessage(CheckStr.Loc,
+                        CheckPrefix+
+                        "-NEXT: is not on the line after the previous match",
+                        "error");
+        SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
+                        "'next' match was here", "note");
+        SM.PrintMessage(SMLoc::getFromPointer(LastMatch),
+                        "previous match was here", "note");
+        return 1;
+      }
+    }
+    
+    // If this match had "not strings", verify that they don't exist in the
+    // skipped region.
+    for (unsigned ChunkNo = 0, e = CheckStr.NotStrings.size();
+         ChunkNo != e; ++ChunkNo) {
+      size_t MatchLen = 0;
+      size_t Pos = CheckStr.NotStrings[ChunkNo].second.Match(SkippedRegion,
+                                                             MatchLen,
+                                                             VariableTable);
+      if (Pos == StringRef::npos) continue;
+     
+      SM.PrintMessage(SMLoc::getFromPointer(LastMatch+Pos),
+                      CheckPrefix+"-NOT: string occurred!", "error");
+      SM.PrintMessage(CheckStr.NotStrings[ChunkNo].first,
+                      CheckPrefix+"-NOT: pattern specified here", "note");
+      return 1;
+    }
+    
+
+    // Otherwise, everything is good.  Step over the matched text and remember
+    // the position after the match as the end of the last match.
+    Buffer = Buffer.substr(MatchLen);
+    LastMatch = Buffer.data();
+  }
+  
+  return 0;
+}
diff --git a/src/LLVM/utils/FileCheck/Makefile b/src/LLVM/utils/FileCheck/Makefile
new file mode 100644
index 0000000..f1af5b6
--- /dev/null
+++ b/src/LLVM/utils/FileCheck/Makefile
@@ -0,0 +1,21 @@
+##===- utils/FileCheck/Makefile ----------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+TOOLNAME = FileCheck
+USEDLIBS = LLVMSupport.a LLVMSystem.a
+
+# This tool has no plugins, optimize startup time.
+TOOL_NO_EXPORTS = 1
+
+# Don't install this utility
+NO_INSTALL = 1
+
+include $(LEVEL)/Makefile.common
+
diff --git a/src/LLVM/utils/FileUpdate/CMakeLists.txt b/src/LLVM/utils/FileUpdate/CMakeLists.txt
new file mode 100644
index 0000000..bacbd16
--- /dev/null
+++ b/src/LLVM/utils/FileUpdate/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_executable(FileUpdate
+  FileUpdate.cpp
+  )
+
+target_link_libraries(FileUpdate LLVMSupport LLVMSystem)
+if( MINGW )
+  target_link_libraries(FileUpdate imagehlp psapi)
+endif( MINGW )
+if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD )
+  target_link_libraries(FileUpdate pthread)
+endif()
diff --git a/src/LLVM/utils/FileUpdate/FileUpdate.cpp b/src/LLVM/utils/FileUpdate/FileUpdate.cpp
new file mode 100644
index 0000000..00c2091
--- /dev/null
+++ b/src/LLVM/utils/FileUpdate/FileUpdate.cpp
@@ -0,0 +1,87 @@
+//===- FileUpdate.cpp - Conditionally update a file -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// FileUpdate is a utility for conditionally updating a file from its input
+// based on whether the input differs from the output. It is used to avoid
+// unnecessary modifications in a build system.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Signals.h"
+using namespace llvm;
+
+static cl::opt<bool>
+Quiet("quiet", cl::desc("Don't print unnecessary status information"),
+      cl::init(false));
+
+static cl::opt<std::string>
+InputFilename("input-file", cl::desc("Input file (defaults to stdin)"),
+              cl::init("-"), cl::value_desc("filename"));
+
+static cl::opt<std::string>
+OutputFilename(cl::Positional, cl::desc("<output-file>"), cl::Required);
+
+int main(int argc, char **argv) {
+  sys::PrintStackTraceOnErrorSignal();
+  PrettyStackTraceProgram X(argc, argv);
+  cl::ParseCommandLineOptions(argc, argv);
+
+  // Get the input data.
+  std::string ErrorStr;
+  MemoryBuffer *In =
+    MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), &ErrorStr);
+  if (In == 0) {
+    errs() << argv[0] << ": error: Unable to get input '"
+           << InputFilename << "': " << ErrorStr << '\n';
+    return 1;
+  }
+
+  // Get the output data.
+  MemoryBuffer *Out = MemoryBuffer::getFile(OutputFilename.c_str(), &ErrorStr);
+
+  // If the output exists and the contents match, we are done.
+  if (Out && In->getBufferSize() == Out->getBufferSize() &&
+      memcmp(In->getBufferStart(), Out->getBufferStart(),
+             Out->getBufferSize()) == 0) {
+    if (!Quiet)
+      outs() << argv[0] << ": Not updating '" << OutputFilename
+             << "', contents match input.\n";
+    return 0;
+  }
+
+  delete Out;
+
+  // Otherwise, overwrite the output.
+  if (!Quiet)
+    outs() << argv[0] << ": Updating '" << OutputFilename
+           << "', contents changed.\n";
+  raw_fd_ostream OutStream(OutputFilename.c_str(), ErrorStr,
+                           raw_fd_ostream::F_Binary);
+  if (!ErrorStr.empty()) {
+    errs() << argv[0] << ": Unable to write output '"
+           << OutputFilename << "': " << ErrorStr << '\n';
+    return 1;
+  }
+
+  OutStream.write(In->getBufferStart(), In->getBufferSize());
+  OutStream.close();
+
+  if (OutStream.has_error()) {
+    errs() << argv[0] << ": Could not open output file '"
+           << OutputFilename << "': " << ErrorStr << '\n';
+    OutStream.clear_error();
+    return 1;
+  }
+
+  return 0;
+}
diff --git a/src/LLVM/utils/FileUpdate/Makefile b/src/LLVM/utils/FileUpdate/Makefile
new file mode 100644
index 0000000..5b545c2
--- /dev/null
+++ b/src/LLVM/utils/FileUpdate/Makefile
@@ -0,0 +1,21 @@
+##===- utils/FileUpdate/Makefile ---------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+TOOLNAME = FileUpdate
+USEDLIBS = LLVMSupport.a LLVMSystem.a
+
+# This tool has no plugins, optimize startup time.
+TOOL_NO_EXPORTS = 1
+
+# Don't install this utility
+NO_INSTALL = 1
+
+include $(LEVEL)/Makefile.common
+
diff --git a/src/LLVM/utils/GenLibDeps.pl b/src/LLVM/utils/GenLibDeps.pl
new file mode 100644
index 0000000..f1f7e72
--- /dev/null
+++ b/src/LLVM/utils/GenLibDeps.pl
@@ -0,0 +1,388 @@
+#!/usr/bin/perl -w
+#
+# Program:  GenLibDeps.pl
+#
+# Synopsis: Generate HTML output that shows the dependencies between a set of
+#           libraries. The output of this script should periodically replace 
+#           the similar content in the UsingLibraries.html document.
+#
+# Syntax:   GenLibDeps.pl [-flat] <directory_with_libraries_in_it> [path_to_nm_binary]
+#
+use strict;
+use warnings;
+# Parse arguments... 
+my $FLAT = 0;
+my $WHY = 0;
+my $PEROBJ = 0;
+my $PEROBJINCL = 0;
+while (scalar(@ARGV) and ($_ = $ARGV[0], /^[-+]/)) {
+  shift;
+  last if /^--$/;  # Stop processing arguments on --
+
+  # List command line options here...
+  if (/^-flat$/)     { $FLAT = 1; next; }
+  if (/^-why/)       { $WHY = 1; $FLAT = 1; next; }
+  if (/^-perobj$/)    { $PEROBJ = 1; next; }
+  if (/^-perobjincl/) { $PEROBJINCL = 1; next;}
+  print "Unknown option: $_ : ignoring!\n";
+}
+
+# Give first option a name.
+my $Directory = $ARGV[0];
+if (!defined($Directory) || ! -d "$Directory") {
+  die "First argument must specify the directory containing LLVM libs\n";
+}
+
+my $nmPath = $ARGV[1];
+
+# Find the "dot" program
+my $DotPath="";
+if (!$FLAT) {
+  chomp($DotPath = `which dot`);
+  die "Can't find 'dot'" if (! -x "$DotPath");
+}
+
+if (defined($ENV{NM})) {
+  chomp($nmPath=$ENV{NM});
+}
+
+if (!defined($nmPath) || $nmPath eq "") {
+  chomp($nmPath=`which nm`);
+  die "Can't find 'nm'" if (! -x "$nmPath");
+}
+
+my $ranlibPath;
+if ($PEROBJ) {
+  $ranlibPath = $ARGV[2];
+  if (defined($ENV{RANLIB})) {
+    chomp($ranlibPath=$ENV{RANLIB});
+  }
+
+  if (!defined($ranlibPath) || $ranlibPath eq "") {
+    chomp($ranlibPath=`which ranlib`);
+    die "Can't find 'ranlib'" if (! -x "$ranlibPath");
+  }
+}
+
+# Open the directory and read its contents, sorting by name and differentiating
+# by whether its a library (.a) or an object file (.o)
+opendir DIR,$Directory;
+my @files = readdir DIR;
+closedir DIR;
+my @libs = grep(/libLLVM.*\.(dylib|so|a)$/,sort(@files));
+# Omit the all-of-llvm shared library.
+@libs = grep(!/libLLVM-\d\.\d(svn)?\.(dylib|so)/, @libs);
+my @objs = grep(/LLVM.*\.o$/,sort(@files));
+
+# Declare the hashes we will use to keep track of the library and object file
+# symbol definitions.
+my %libdefs;
+my %objdefs;
+
+my %libobjs;
+my %objdeps=();
+# Gather library definitions at object file granularity (optional)
+if ($PEROBJ) {
+  foreach my $lib (@libs ) {
+    `$ranlibPath $Directory/$lib`;
+    my $libpath = $lib;
+    $libpath =~ s/^libLLVM(.*)\.a/$1/;
+    $libpath =~ s/(.+)CodeGen$/Target\/$1/;
+    $libpath =~ s/(.+)AsmPrinter$/Target\/$1\/AsmPrinter/;
+    $libpath =~ s/(.+)AsmParser$/Target\/$1\/AsmParser/;
+    $libpath =~ s/(.+)Info$/Target\/$1\/TargetInfo/;
+    $libpath =~ s/(.+)Disassembler$/Target\/$1\/Disassembler/;
+    $libpath =~ s/SelectionDAG/CodeGen\/SelectionDAG/;
+    $libpath =~ s/^AsmPrinter/CodeGen\/AsmPrinter/;
+    $libpath =~ s/^BitReader/Bitcode\/Reader/;
+    $libpath =~ s/^BitWriter/Bitcode\/Writer/;
+    $libpath =~ s/^CBackend/Target\/CBackend/;
+    $libpath =~ s/^CppBackend/Target\/CppBackend/;
+    $libpath =~ s/^MSIL/Target\/MSIL/;
+    $libpath =~ s/^Core/VMCore/;
+    $libpath =~ s/^Instrumentation/Transforms\/Instrumentation/;
+    $libpath =~ s/^Interpreter/ExecutionEngine\/Interpreter/;
+    $libpath =~ s/^JIT/ExecutionEngine\/JIT/;
+    $libpath =~ s/^ScalarOpts/Transforms\/Scalar/;
+    $libpath =~ s/^TransformUtils/Transforms\/Utils/;
+    $libpath =~ s/^ipa/Analysis\/IPA/;
+    $libpath =~ s/^ipo/Transforms\/IPO/;
+    $libpath =~ s/^pic16passes/Target\/PIC16\/PIC16Passes/;
+    $libpath = "lib/".$libpath."/";
+    open DEFS, "$nmPath -sg $Directory/$lib|";
+    while (<DEFS>) {
+      chomp;
+      if (/^([^ ]*) in ([^ ]*)/) {
+        my $objfile = $libpath.$2;
+        $objdefs{$1} = $objfile;
+        $objdeps{$objfile} = {};
+        $libobjs{$lib}{$objfile}=1;
+#        my $p = "../llvm/".$objfile;
+#        $p =~ s/Support\/reg(.*).o/Support\/reg$1.c/;
+#        $p =~ s/.o$/.cpp/;
+#        unless (-e $p) {
+#          die "$p\n"
+#        }
+      }
+    }
+    close DEFS or die "nm failed";
+  }
+  foreach my $lib (@libs ) {
+    my $libpath = $lib;
+    $libpath =~ s/^libLLVM(.*)\.a/$1/;
+    $libpath =~ s/(.+)CodeGen$/Target\/$1/;
+    $libpath =~ s/(.+)AsmPrinter$/Target\/$1\/AsmPrinter/;
+    $libpath =~ s/(.+)AsmParser$/Target\/$1\/AsmParser/;
+    $libpath =~ s/(.+)Info$/Target\/$1\/TargetInfo/;
+    $libpath =~ s/(.+)Disassembler$/Target\/$1\/Disassembler/;
+    $libpath =~ s/SelectionDAG/CodeGen\/SelectionDAG/;
+    $libpath =~ s/^AsmPrinter/CodeGen\/AsmPrinter/;
+    $libpath =~ s/^BitReader/Bitcode\/Reader/;
+    $libpath =~ s/^BitWriter/Bitcode\/Writer/;
+    $libpath =~ s/^CBackend/Target\/CBackend/;
+    $libpath =~ s/^CppBackend/Target\/CppBackend/;
+    $libpath =~ s/^MSIL/Target\/MSIL/;
+    $libpath =~ s/^Core/VMCore/;
+    $libpath =~ s/^Instrumentation/Transforms\/Instrumentation/;
+    $libpath =~ s/^Interpreter/ExecutionEngine\/Interpreter/;
+    $libpath =~ s/^JIT/ExecutionEngine\/JIT/;
+    $libpath =~ s/^ScalarOpts/Transforms\/Scalar/;
+    $libpath =~ s/^TransformUtils/Transforms\/Utils/;
+    $libpath =~ s/^ipa/Analysis\/IPA/;
+    $libpath =~ s/^ipo/Transforms\/IPO/;
+    $libpath =~ s/^pic16passes/Target\/PIC16\/PIC16Passes/;
+    $libpath = "lib/".$libpath."/";
+    open UDEFS, "$nmPath -Aup $Directory/$lib|";
+    while (<UDEFS>) {
+      chomp;
+      if (/:([^:]+):/) {
+        my $obj = $libpath.$1;
+        s/[^ ]+: *U //;
+        if (defined($objdefs{$_})) {
+          $objdeps{$obj}{$objdefs{$_}}=1;
+        }
+      }
+    }
+    close UDEFS or die "nm failed"
+  }
+} else {
+# Gather definitions from the libraries
+foreach my $lib (@libs ) {
+  open DEFS, "$nmPath -g $Directory/$lib|";
+  while (<DEFS>) {
+    next if (! / [ABCDGRST] /);
+    s/^[^ ]* [ABCDGRST] //;    
+    s/\015?\012//; # not sure if <DEFS> is in binmode and uses LF or CRLF.
+                   # this strips both LF and CRLF.
+    $libdefs{$_} = $lib;
+  }
+  close DEFS or die "nm failed";
+}
+}
+
+# Gather definitions from the object files.
+foreach my $obj (@objs ) {
+  open DEFS, "$nmPath -g $Directory/$obj |";
+  while (<DEFS>) {
+    next if (! / [ABCDGRST] /);
+    s/^[^ ]* [ABCDGRST] //;
+    s/\015?\012//; # not sure if <DEFS> is in binmode and uses LF or CRLF.
+                   # this strips both LF and CRLF.    
+    $objdefs{$_} = $obj;
+  }
+  close DEFS or die "nm failed";
+}
+
+# Generate one entry in the <dl> list. This generates the <dt> and <dd> elements
+# for one library or object file. The <dt> provides the name of the library or
+# object. The <dd> provides a list of the libraries/objects it depends on.
+sub gen_one_entry {
+  my $lib = $_[0];
+  my $lib_ns = $lib;
+  $lib_ns =~ s/(.*)\.[oa]/$1/;
+  if ($FLAT) {
+    print "$lib:";
+    if ($WHY) { print "\n"; }
+  } else {
+    print "  <dt><b>$lib</b</dt><dd><ul>\n";
+  }
+  open UNDEFS, 
+    "$nmPath -u $Directory/$lib | sed -e 's/^[ 0]* U //' | sort | uniq |";
+  my %DepLibs;
+  while (<UNDEFS>) {
+    chomp;
+    my $lib_printed = 0;
+    if (defined($libdefs{$_}) && $libdefs{$_} ne $lib) {
+      $DepLibs{$libdefs{$_}} = [] unless exists $DepLibs{$libdefs{$_}};
+      push(@{$DepLibs{$libdefs{$_}}}, $_);
+    } elsif (defined($objdefs{$_}) && $objdefs{$_} ne $lib) {
+      if ($PEROBJ && !$PEROBJINCL) {
+        # -perobjincl makes .a files depend on .o files they contain themselves
+        # default is don't depend on these.
+        next if defined $libobjs{$lib}{$objdefs{$_}};
+      }
+      my $libroot = $lib;
+      $libroot =~ s/lib(.*).a/$1/;
+      if ($objdefs{$_} ne "$libroot.o") {
+        $DepLibs{$objdefs{$_}} = [] unless exists $DepLibs{$objdefs{$_}};
+        push(@{$DepLibs{$objdefs{$_}}}, $_);
+      }
+    }
+  }
+  close UNDEFS or die "nm failed";
+  unless(keys %DepLibs) {
+    # above failed
+    open UNDEFS, "$nmPath -u $Directory/$lib |";
+    while (<UNDEFS>) {
+      # to bypass non-working sed
+      if ('  ' eq substr($_,0,2) and index($_,'U ')) {
+        $_ = substr($_,index($_,'U ')+2)
+      };
+      $_ = substr($_,index($_,'  *U ')+5) if -1!=index($_,'  *U ');
+
+      chomp;
+      my $lib_printed = 0;
+      if (defined($libdefs{$_}) && $libdefs{$_} ne $lib) {
+        $DepLibs{$libdefs{$_}} = [] unless exists $DepLibs{$libdefs{$_}};
+        push(@{$DepLibs{$libdefs{$_}}}, $_);
+      } elsif (defined($objdefs{$_}) && $objdefs{$_} ne $lib) {
+        my $libroot = $lib;
+        $libroot =~ s/lib(.*).a/$1/;
+        if ($objdefs{$_} ne "$libroot.o") {
+          $DepLibs{$objdefs{$_}} = [] unless exists $DepLibs{$objdefs{$_}};
+          push(@{$DepLibs{$objdefs{$_}}}, $_);
+        }
+      }
+    }
+    close UNDEFS or die "nm failed";
+  }
+  if ($PEROBJINCL) {
+     # include the .a's objects
+     for my $obj (keys %{$libobjs{$lib}}) {
+        $DepLibs{$obj} = ["<.a object>"] unless exists $DepLibs{$obj};
+     }
+     my $madechange = 1;
+     while($madechange) {
+      $madechange = 0;
+      my %temp = %DepLibs;
+      foreach my $obj (keys %DepLibs) {
+        foreach my $objdeps (keys %{$objdeps{$obj}}) {
+          next if defined $temp{$objdeps};
+          push(@{$temp{$objdeps}}, $obj);
+          $madechange = 1;
+        }
+      }
+      %DepLibs = %temp;
+     }
+  }
+
+  for my $key (sort keys %DepLibs) {
+    if ($FLAT) {
+      print " $key";
+      if ($WHY) {
+        print "\n";
+        my @syms = @{$DepLibs{$key}};
+        foreach my $sym (@syms) {
+          print "  $sym\n";
+        }
+      }
+    } else {
+      print "    <li>$key</li>\n";
+    }
+    my $suffix = substr($key,length($key)-1,1);
+    $key =~ s/(.*)\.[oa]/$1/;
+    if ($suffix eq "a") {
+      if (!$FLAT) { print DOT "$lib_ns -> $key [ weight=0 ];\n" };
+    } else {
+      if (!$FLAT) { print DOT "$lib_ns -> $key [ weight=10];\n" };
+    }
+  }
+  if ($FLAT) {
+    if (!$WHY) {
+      print "\n";
+    }
+  } else {
+    print "  </ul></dd>\n";
+  }
+}
+
+# Make sure we flush on write. This is slower but correct based on the way we
+# write I/O in gen_one_entry.
+$| = 1;
+
+# Print the definition list tag
+if (!$FLAT) {
+    print "<dl>\n";
+
+  open DOT, "| $DotPath -Tgif > libdeps.gif";
+
+  print DOT "digraph LibDeps {\n";
+  print DOT "  size=\"40,15\"; \n";
+  print DOT "  ratio=\"1.33333\"; \n";
+  print DOT "  margin=\"0.25\"; \n";
+  print DOT "  rankdir=\"LR\"; \n";
+  print DOT "  mclimit=\"50.0\"; \n";
+  print DOT "  ordering=\"out\"; \n";
+  print DOT "  center=\"1\";\n";
+  print DOT "node [shape=\"box\",\n";
+  print DOT "      color=\"#000088\",\n";
+  print DOT "      fillcolor=\"#FFFACD\",\n";
+  print DOT "      fontcolor=\"#3355BB\",\n";
+  print DOT "      style=\"filled\",\n";
+  print DOT "      fontname=\"sans\",\n";
+  print DOT "      fontsize=\"24\"\n";
+  print DOT "];\n";
+  print DOT "edge [dir=\"forward\",style=\"solid\",color=\"#000088\"];\n";
+}
+
+# Print libraries first
+foreach my $lib (@libs) {
+  gen_one_entry($lib);
+}
+
+if ($PEROBJ) {
+  foreach my $obj (keys %objdeps) {
+     print "$obj:";
+     if (!$PEROBJINCL) {
+      foreach my $dep (keys %{$objdeps{$obj}}) {
+          print " $dep";
+      }
+    }
+     print "\n";
+  }
+}
+
+if (!$FLAT) {
+  print DOT "}\n";
+  close DOT;
+  open DOT, "| $DotPath -Tgif > objdeps.gif";
+  print DOT "digraph ObjDeps {\n";
+  print DOT "  size=\"8,10\";\n";
+  print DOT "  margin=\"0.25\";\n";
+  print DOT "  rankdir=\"LR\";\n";
+  print DOT "  mclimit=\"50.0\";\n";
+  print DOT "  ordering=\"out\";\n";
+  print DOT "  center=\"1\";\n";
+  print DOT "node [shape=\"box\",\n";
+  print DOT "      color=\"#000088\",\n";
+  print DOT "      fillcolor=\"#FFFACD\",\n";
+  print DOT "      fontcolor=\"#3355BB\",\n";
+  print DOT "      fontname=\"sans\",\n";
+  print DOT "      style=\"filled\",\n";
+  print DOT "      fontsize=\"24\"\n";
+  print DOT "];\n";
+  print DOT "edge [dir=\"forward\",style=\"solid\",color=\"#000088\"];\n";
+}
+
+# Print objects second
+foreach my $obj (@objs) {
+  gen_one_entry($obj);
+}
+
+if (!$FLAT) {
+  print DOT "}\n";
+  close DOT;
+
+# Print end tag of definition list element
+  print "</dl>\n";
+}
diff --git a/src/LLVM/utils/GetSourceVersion b/src/LLVM/utils/GetSourceVersion
new file mode 100644
index 0000000..b25f2f9
--- /dev/null
+++ b/src/LLVM/utils/GetSourceVersion
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+usage() {
+   echo "usage: $0 <source root>"
+   echo "  Prints the source control revision of the given source directory,"
+   echo "  the exact format of the revision string depends on the source "
+   echo "  control system. If the source control system isn't known, the output"
+   echo "  is empty and the exit code is 1."
+   exit 1
+}
+
+if [ $# != 1 ] || [ ! -d $1 ]; then
+  usage;
+fi
+
+cd $1
+if [ -d .svn ]; then
+   svnversion
+elif [ -d .git/svn ]; then
+   git svn info | grep 'Revision:' | cut -d: -f2-
+elif [ -d .git ]; then
+   git log -1 --pretty=format:%H
+else
+   exit 1;
+fi
+
+exit 0
diff --git a/src/LLVM/utils/Makefile b/src/LLVM/utils/Makefile
new file mode 100644
index 0000000..1a4dcca
--- /dev/null
+++ b/src/LLVM/utils/Makefile
@@ -0,0 +1,22 @@
+##===- utils/Makefile --------------------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+LEVEL = ..
+PARALLEL_DIRS := FileCheck FileUpdate TableGen PerfectShuffle \
+	      count fpcmp llvm-lit not unittest
+
+EXTRA_DIST := cgiplotNLT.pl check-each-file codegen-diff countloc.sh \
+              DSAclean.py DSAextract.py emacs findsym.pl GenLibDeps.pl \
+	      getsrcs.sh importNLT.pl llvmdo llvmgrep llvm-native-gcc \
+	      llvm-native-gxx makellvm NightlyTest.gnuplot NightlyTest.pl \
+	      NightlyTestTemplate.html NLT.schema OldenDataRecover.pl \
+	      parseNLT.pl plotNLT.pl profile.pl \
+	      webNLT.pl vim
+
+include $(LEVEL)/Makefile.common
diff --git a/src/LLVM/utils/NLT.schema b/src/LLVM/utils/NLT.schema
new file mode 100644
index 0000000..0e39814
--- /dev/null
+++ b/src/LLVM/utils/NLT.schema
@@ -0,0 +1,8 @@
+CREATE TABLE `Tests` (

+  `NAME` varchar(255) NOT NULL default '',

+  `RUN` date NOT NULL default '0000-00-00',

+  `TEST` varchar(32) NOT NULL default '',

+  `VALUE` double NOT NULL default '0',

+  KEY `name_index` (`NAME`)

+) ENGINE=MyISAM DEFAULT CHARSET=latin1

+

diff --git a/src/LLVM/utils/NewNightlyTest.pl b/src/LLVM/utils/NewNightlyTest.pl
new file mode 100644
index 0000000..1b48168
--- /dev/null
+++ b/src/LLVM/utils/NewNightlyTest.pl
@@ -0,0 +1,836 @@
+#!/usr/bin/perl
+use POSIX qw(strftime);
+use File::Copy;
+use File::Find;
+use Socket;
+
+#
+# Program:  NewNightlyTest.pl
+#
+# Synopsis: Perform a series of tests which are designed to be run nightly.
+#           This is used to keep track of the status of the LLVM tree, tracking
+#           regressions and performance changes. Submits this information
+#           to llvm.org where it is placed into the nightlytestresults database.
+#
+# Syntax:   NightlyTest.pl [OPTIONS] [CVSROOT BUILDDIR WEBDIR]
+#   where
+# OPTIONS may include one or more of the following:
+#
+# MAIN OPTIONS:
+#  -config LLVMPATH If specified, use an existing LLVM build and only run and
+#                   report the test information. The LLVMCONFIG argument should
+#                   be the path to the llvm-config executable in the LLVM build.
+#                   This should be the first argument if given. NOT YET
+#                   IMPLEMENTED.
+#  -nickname NAME   The NAME argument specifieds the nickname this script
+#                   will submit to the nightlytest results repository.
+#  -nouname         Don't include uname data (machine will be identified by nickname only).
+#  -submit-server   Specifies a server to submit the test results too. If this
+#                   option is not specified it defaults to
+#                   llvm.org. This is basically just the address of the
+#                   webserver
+#  -submit-script   Specifies which script to call on the submit server. If
+#                   this option is not specified it defaults to
+#                   /nightlytest/NightlyTestAccept.php. This is basically
+#                   everything after the www.yourserver.org.
+#  -submit-aux      If specified, an auxiliary script to run in addition to the
+#                   normal submit script. The script will be passed the path to
+#                   the "sentdata.txt" file as its sole argument.
+#  -nosubmit        Do not report the test results back to a submit server.
+#
+#
+# BUILD OPTIONS (not used with -config):
+#  -nocheckout      Do not create, checkout, update, or configure
+#                   the source tree.
+#  -noremove        Do not remove the BUILDDIR after it has been built.
+#  -noremoveresults Do not remove the WEBDIR after it has been built.
+#  -noclean         Do not run 'make clean' before building.
+#  -nobuild         Do not build llvm. If tests are enabled perform them
+#                   on the llvm build specified in the build directory
+#  -release         Build an LLVM Release+Asserts version
+#  -release-asserts Build an LLVM Release version
+#  -disable-bindings     Disable building LLVM bindings.
+#  -with-clang      Checkout Clang source into tools/clang.
+#  -compileflags    Next argument specifies extra options passed to make when
+#                   building LLVM.
+#  -use-gmake       Use gmake instead of the default make command to build
+#                   llvm and run tests.
+#  -llvmgccdir      Next argument specifies the llvm-gcc install prefix.
+#
+# TESTING OPTIONS:
+#  -notest          Do not even attempt to run the test programs.
+#  -nodejagnu       Do not run feature or regression tests
+#  -enable-llcbeta  Enable testing of beta features in llc.
+#  -enable-lli      Enable testing of lli (interpreter) features, default is off
+#  -disable-pic	    Disable building with Position Independent Code.
+#  -disable-llc     Disable LLC tests in the nightly tester.
+#  -disable-jit     Disable JIT tests in the nightly tester.
+#  -disable-cbe     Disable C backend tests in the nightly tester.
+#  -disable-lto     Disable link time optimization.
+#  -test-cflags     Next argument specifies that C compilation options that
+#                   override the default when running the testsuite.
+#  -test-cxxflags   Next argument specifies that C++ compilation options that
+#                   override the default when running the testsuite.
+#  -extraflags      Next argument specifies extra options that are passed to
+#                   compile the tests.
+#  -noexternals     Do not run the external tests (for cases where povray
+#                   or SPEC are not installed)
+#  -with-externals  Specify a directory where the external tests are located.
+#
+# OTHER OPTIONS:
+#  -parallel        Run parallel jobs with GNU Make (see -parallel-jobs).
+#  -parallel-jobs   The number of parallel Make jobs to use (default is two).
+#  -parallel-test   Allow parallel execution of llvm-test
+#  -verbose         Turn on some debug output
+#  -nice            Checkout/Configure/Build with "nice" to reduce impact
+#                   on busy servers.
+#  -f2c             Next argument specifies path to F2C utility
+#  -gccpath         Path to gcc/g++ used to build LLVM
+#  -target          Specify the target triplet
+#  -cflags          Next argument specifies that C compilation options that
+#                   override the default.
+#  -cxxflags        Next argument specifies that C++ compilation options that
+#                   override the default.
+#  -ldflags         Next argument specifies that linker options that override
+#                   the default.
+#
+# CVSROOT is ignored, it is passed for backwards compatibility.
+# BUILDDIR is the directory where sources for this test run will be checked out
+#  AND objects for this test run will be built. This directory MUST NOT
+#  exist before the script is run; it will be created by the svn checkout
+#  process and erased (unless -noremove is specified; see above.)
+# WEBDIR is the directory into which the test results web page will be written,
+#  AND in which the "index.html" is assumed to be a symlink to the most recent
+#  copy of the results. This directory will be created if it does not exist.
+# LLVMGCCDIR is the directory in which the LLVM GCC Front End is installed
+#  to. This is the same as you would have for a normal LLVM build.
+#
+##############################################################
+#
+# Getting environment variables
+#
+##############################################################
+my $HOME       = $ENV{'HOME'};
+my $SVNURL     = $ENV{"SVNURL"};
+$SVNURL        = 'http://llvm.org/svn/llvm-project' unless $SVNURL;
+my $TestSVNURL = $ENV{"TestSVNURL"};
+$TestSVNURL    = 'http://llvm.org/svn/llvm-project' unless $TestSVNURL;
+my $BuildDir   = $ENV{'BUILDDIR'};
+my $WebDir     = $ENV{'WEBDIR'};
+
+##############################################################
+#
+# Calculate the date prefix...
+#
+##############################################################
+use POSIX;
+@TIME = localtime;
+my $DATE = strftime("%Y-%m-%d_%H-%M-%S", localtime());
+
+##############################################################
+#
+# Parse arguments...
+#
+##############################################################
+$CONFIG_PATH="";
+$CONFIGUREARGS="";
+$nickname="";
+$NOTEST=0;
+$MAKECMD="make";
+$SUBMITSERVER = "llvm.org";
+$SUBMITSCRIPT = "/nightlytest/NightlyTestAccept.php";
+$SUBMITAUX="";
+$SUBMIT = 1;
+$PARALLELJOBS = "2";
+my $TESTFLAGS="";
+
+if ($ENV{'LLVMGCCDIR'}) {
+  $CONFIGUREARGS .= " --with-llvmgccdir=" . $ENV{'LLVMGCCDIR'};
+  $LLVMGCCPATH = $ENV{'LLVMGCCDIR'} . '/bin';
+}
+else {
+  $LLVMGCCPATH = "";
+}
+
+while (scalar(@ARGV) and ($_ = $ARGV[0], /^[-+]/)) {
+  shift;
+  last if /^--$/;  # Stop processing arguments on --
+
+  # List command line options here...
+  if (/^-config$/)         { $CONFIG_PATH = "$ARGV[0]"; shift; next; }
+  if (/^-nocheckout$/)     { $NOCHECKOUT = 1; next; }
+  if (/^-noclean$/)        { $NOCLEAN = 1; next; }
+  if (/^-noremove$/)       { $NOREMOVE = 1; next; }
+  if (/^-noremoveatend$/)  { $NOREMOVEATEND = 1; next; }
+  if (/^-noremoveresults$/){ $NOREMOVERESULTS = 1; next; }
+  if (/^-notest$/)         { $NOTEST = 1; next; }
+  if (/^-norunningtests$/) { next; } # Backward compatibility, ignored.
+  if (/^-parallel-jobs$/)  { $PARALLELJOBS = "$ARGV[0]"; shift; next;}
+  if (/^-parallel$/)       { $MAKEOPTS = "$MAKEOPTS -j$PARALLELJOBS"; next; }
+  if (/^-parallel-test$/)  { $PROGTESTOPTS .= " ENABLE_PARALLEL_REPORT=1"; next; }
+  if (/^-with-clang$/)     { $WITHCLANG = 1; next; }
+  if (/^-release$/)        { $MAKEOPTS = "$MAKEOPTS ENABLE_OPTIMIZED=1 ".
+                             "OPTIMIZE_OPTION=-O2"; next;}
+  if (/^-release-asserts$/){ $MAKEOPTS = "$MAKEOPTS ENABLE_OPTIMIZED=1 ".
+                             "DISABLE_ASSERTIONS=1 ".
+                             "OPTIMIZE_OPTION=-O2"; next;}
+  if (/^-enable-llcbeta$/) { $PROGTESTOPTS .= " ENABLE_LLCBETA=1"; next; }
+  if (/^-disable-pic$/)    { $CONFIGUREARGS .= " --enable-pic=no"; next; }
+  if (/^-enable-lli$/)     { $PROGTESTOPTS .= " ENABLE_LLI=1";
+                             $CONFIGUREARGS .= " --enable-lli"; next; }
+  if (/^-disable-llc$/)    { $PROGTESTOPTS .= " DISABLE_LLC=1";
+                             $CONFIGUREARGS .= " --disable-llc_diffs"; next; }
+  if (/^-disable-jit$/)    { $PROGTESTOPTS .= " DISABLE_JIT=1";
+                             $CONFIGUREARGS .= " --disable-jit"; next; }
+  if (/^-disable-bindings$/)    { $CONFIGUREARGS .= " --disable-bindings"; next; }
+  if (/^-disable-cbe$/)    { $PROGTESTOPTS .= " DISABLE_CBE=1"; next; }
+  if (/^-disable-lto$/)    { $PROGTESTOPTS .= " DISABLE_LTO=1"; next; }
+  if (/^-test-opts$/)      { $PROGTESTOPTS .= " $ARGV[0]"; shift; next; }
+  if (/^-verbose$/)        { $VERBOSE = 1; next; }
+  if (/^-teelogs$/)        { $TEELOGS = 1; next; }
+  if (/^-nice$/)           { $NICE = "nice "; next; }
+  if (/^-f2c$/)            { $CONFIGUREARGS .= " --with-f2c=$ARGV[0]";
+                             shift; next; }
+  if (/^-with-externals$/) { $CONFIGUREARGS .= " --with-externals=$ARGV[0]";
+                             shift; next; }
+  if (/^-configure-args$/) { $CONFIGUREARGS .= " $ARGV[0]";
+                             shift; next; }
+  if (/^-submit-server/)   { $SUBMITSERVER = "$ARGV[0]"; shift; next; }
+  if (/^-submit-script/)   { $SUBMITSCRIPT = "$ARGV[0]"; shift; next; }
+  if (/^-submit-aux/)      { $SUBMITAUX = "$ARGV[0]"; shift; next; }
+  if (/^-nosubmit$/)       { $SUBMIT = 0; next; }
+  if (/^-nickname$/)       { $nickname = "$ARGV[0]"; shift; next; }
+  if (/^-gccpath/)         { $CONFIGUREARGS .=
+                             " CC=$ARGV[0]/gcc CXX=$ARGV[0]/g++";
+                             $GCCPATH=$ARGV[0]; shift;  next; }
+  else                     { $GCCPATH=""; }
+  if (/^-target/)          { $CONFIGUREARGS .= " --target=$ARGV[0]";
+                             shift; next; }
+  if (/^-cflags/)          { $MAKEOPTS = "$MAKEOPTS C.Flags=\'$ARGV[0]\'";
+                             shift; next; }
+  if (/^-cxxflags/)        { $MAKEOPTS = "$MAKEOPTS CXX.Flags=\'$ARGV[0]\'";
+                             shift; next; }
+  if (/^-ldflags/)         { $MAKEOPTS = "$MAKEOPTS LD.Flags=\'$ARGV[0]\'";
+                             shift; next; }
+  if (/^-test-cflags/)     { $TESTFLAGS = "$TESTFLAGS CFLAGS=\'$ARGV[0]\'";
+                             shift; next; }
+  if (/^-test-cxxflags/)   { $TESTFLAGS = "$TESTFLAGS CXXFLAGS=\'$ARGV[0]\'";
+                             shift; next; }
+  if (/^-compileflags/)    { $MAKEOPTS = "$MAKEOPTS $ARGV[0]"; shift; next; }
+  if (/^-llvmgccdir/)      { $CONFIGUREARGS .= " --with-llvmgccdir=\'$ARGV[0]\'";
+                             $LLVMGCCPATH = $ARGV[0] . '/bin';
+                             shift; next;}
+  if (/^-noexternals$/)    { $NOEXTERNALS = 1; next; }
+  if (/^-nouname$/)        { $NOUNAME = 1; next; }
+  if (/^-use-gmake/)       { $MAKECMD = "gmake"; shift; next; }
+  if (/^-extraflags/)      { $CONFIGUREARGS .=
+                             " --with-extra-options=\'$ARGV[0]\'"; shift; next;}
+  if (/^-noexternals$/)    { $NOEXTERNALS = 1; next; }
+  if (/^-nodejagnu$/)      { next; }
+  if (/^-nobuild$/)        { $NOBUILD = 1; next; }
+  print "Unknown option: $_ : ignoring!\n";
+}
+
+if ($CONFIGUREARGS !~ /--disable-jit/) {
+  $CONFIGUREARGS .= " --enable-jit";
+}
+
+if (@ARGV != 0 and @ARGV != 3) {
+  die "error: must specify 0 or 3 options!";
+}
+
+if (@ARGV == 3) {
+  if ($CONFIG_PATH ne "") {
+      die "error: arguments are unsupported in -config mode,";
+  }
+
+  # ARGV[0] used to be the CVS root, ignored for backward compatibility.
+  $BuildDir   = $ARGV[1];
+  $WebDir     = $ARGV[2];
+}
+
+if ($CONFIG_PATH ne "") {
+  $BuildDir = "";
+  $SVNURL = $TestSVNURL = "";
+  if ($WebDir     eq "") {
+    die("please specify a web directory");
+  }
+} else {
+  if ($BuildDir   eq "" or
+      $WebDir     eq "") {
+    die("please specify a build directory, and a web directory");
+  }
+}
+
+if ($nickname eq "") {
+  die ("Please invoke NewNightlyTest.pl with command line option " .
+       "\"-nickname <nickname>\"");
+}
+
+my $LLVMSrcDir   = $ENV{'LLVMSRCDIR'};
+$LLVMSrcDir    = "$BuildDir/llvm" unless $LLVMSrcDir;
+my $LLVMObjDir   = $ENV{'LLVMOBJDIR'};
+$LLVMObjDir    = "$BuildDir/llvm" unless $LLVMObjDir;
+my $LLVMTestDir   = $ENV{'LLVMTESTDIR'};
+$LLVMTestDir    = "$BuildDir/llvm/projects/llvm-test" unless $LLVMTestDir;
+
+##############################################################
+#
+# Define the file names we'll use
+#
+##############################################################
+
+my $Prefix = "$WebDir/$DATE";
+my $SingleSourceLog = "$Prefix-SingleSource-ProgramTest.txt.gz";
+my $MultiSourceLog = "$Prefix-MultiSource-ProgramTest.txt.gz";
+my $ExternalLog = "$Prefix-External-ProgramTest.txt.gz";
+
+# These are only valid in non-config mode.
+my $ConfigureLog = "", $BuildLog = "", $COLog = "";
+my $DejagnuLog = "", $DejagnuSum = "", $DejagnuLog = "";
+
+# Are we in config mode?
+my $ConfigMode = 0;
+
+##############################################################
+#
+# Helper functions
+#
+##############################################################
+
+sub GetDir {
+  my $Suffix = shift;
+  opendir DH, $WebDir;
+  my @Result = reverse sort grep !/$DATE/, grep /[-0-9]+$Suffix/, readdir DH;
+  closedir DH;
+  return @Result;
+}
+
+sub RunLoggedCommand {
+  my $Command = shift;
+  my $Log = shift;
+  my $Title = shift;
+  if ($TEELOGS) {
+      if ($VERBOSE) {
+          print "$Title\n";
+          print "$Command 2>&1 | tee $Log\n";
+      }
+      system "$Command 2>&1 | tee $Log";
+  } else {
+      if ($VERBOSE) {
+          print "$Title\n";
+          print "$Command > $Log 2>&1\n";
+      }
+      system "$Command > $Log 2>&1";
+  }
+}
+
+sub RunAppendingLoggedCommand {
+  my $Command = shift;
+  my $Log = shift;
+  my $Title = shift;
+  if ($TEELOGS) {
+      if ($VERBOSE) {
+          print "$Title\n";
+          print "$Command 2>&1 | tee -a $Log\n";
+      }
+      system "$Command 2>&1 | tee -a $Log";
+  } else {
+      if ($VERBOSE) {
+          print "$Title\n";
+          print "$Command >> $Log 2>&1\n";
+      }
+      system "$Command >> $Log 2>&1";
+  }
+}
+
+sub GetRegex {   # (Regex with ()'s, value)
+  if ($_[1] =~ /$_[0]/m) {
+    return $1;
+  }
+  return "0";
+}
+
+sub ChangeDir { # directory, logical name
+  my ($dir,$name) = @_;
+  chomp($dir);
+  if ( $VERBOSE ) { print "Changing To: $name ($dir)\n"; }
+  $result = chdir($dir);
+  if (!$result) {
+    print "ERROR!!! Cannot change directory to: $name ($dir) because $!\n";
+    return false;
+  }
+  return true;
+}
+
+sub ReadFile {
+  if (open (FILE, $_[0])) {
+    undef $/;
+    my $Ret = <FILE>;
+    close FILE;
+    $/ = '\n';
+    return $Ret;
+  } else {
+    print "Could not open file '$_[0]' for reading!\n";
+    return "";
+  }
+}
+
+sub WriteFile {  # (filename, contents)
+  open (FILE, ">$_[0]") or die "Could not open file '$_[0]' for writing!\n";
+  print FILE $_[1];
+  close FILE;
+}
+
+sub CopyFile { #filename, newfile
+  my ($file, $newfile) = @_;
+  chomp($file);
+  if ($VERBOSE) { print "Copying $file to $newfile\n"; }
+  copy($file, $newfile);
+}
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+# This function acts as a mini web browswer submitting data
+# to our central server via the post method
+#
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+sub WriteSentData {
+    $variables = $_[0];
+
+    # Write out the "...-sentdata.txt" file.
+
+    my $sentdata="";
+    foreach $x (keys (%$variables)){
+        $value = $variables->{$x};
+        $sentdata.= "$x  => $value\n";
+    }
+    WriteFile "$Prefix-sentdata.txt", $sentdata;
+}
+
+sub SendData {
+    $host = $_[0];
+    $file = $_[1];
+    $variables = $_[2];
+
+    if (!($SUBMITAUX eq "")) {
+        system "$SUBMITAUX \"$Prefix-sentdata.txt\"";
+    }
+
+    if (!$SUBMIT) {
+        return "Skipped standard submit.\n";
+    }
+
+    # Create the content to send to the server.
+
+    my $content;
+    foreach $key (keys (%$variables)){
+        $value = $variables->{$key};
+        $value =~ s/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg;
+        $content .= "$key=$value&";
+    }
+
+    # Send the data to the server.
+    #
+    # FIXME: This code should be more robust?
+
+    $port=80;
+    $socketaddr= sockaddr_in $port, inet_aton $host or die "Bad hostname\n";
+    socket SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp') or
+      die "Bad socket\n";
+    connect SOCK, $socketaddr or die "Bad connection\n";
+    select((select(SOCK), $| = 1)[0]);
+
+    $length = length($content);
+
+    my $send= "POST $file HTTP/1.0\n";
+    $send.= "Host: $host\n";
+    $send.= "Content-Type: application/x-www-form-urlencoded\n";
+    $send.= "Content-length: $length\n\n";
+    $send.= "$content";
+
+    print SOCK $send;
+    my $result;
+    while(<SOCK>){
+        $result  .= $_;
+    }
+    close(SOCK);
+
+    return $result;
+}
+
+##############################################################
+#
+# Individual Build & Test Functions
+#
+##############################################################
+
+# Create the source repository directory.
+sub CheckoutSource {
+  die "Invalid call!" unless $ConfigMode == 0;
+  if (-d $BuildDir) {
+    if (!$NOREMOVE) {
+      if ( $VERBOSE ) {
+        print "Build directory exists! Removing it\n";
+      }
+      system "rm -rf $BuildDir";
+      mkdir $BuildDir or die "Could not create checkout directory $BuildDir!";
+    } else {
+      if ( $VERBOSE ) {
+        print "Build directory exists!\n";
+      }
+    }
+  } else {
+    mkdir $BuildDir or die "Could not create checkout directory $BuildDir!";
+  }
+
+  ChangeDir( $BuildDir, "checkout directory" );
+  my $SVNCMD = "$NICE svn co --non-interactive";
+  RunLoggedCommand("( time -p $SVNCMD $SVNURL/llvm/trunk llvm; cd llvm/projects ; " .
+                   "  $SVNCMD $TestSVNURL/test-suite/trunk llvm-test )", $COLog,
+                   "CHECKOUT LLVM");
+  if ($WITHCLANG) {
+      RunLoggedCommand("( cd llvm/tools ; " .
+                       "  $SVNCMD $SVNURL/cfe/trunk clang )", $COLog,
+                       "CHECKOUT CLANG");
+  }
+}
+
+# Build the entire tree, saving build messages to the build log. Returns false
+# on build failure.
+sub BuildLLVM {
+  die "Invalid call!" unless $ConfigMode == 0;
+  my $EXTRAFLAGS = "--enable-spec --with-objroot=.";
+  RunLoggedCommand("(time -p $NICE ./configure $CONFIGUREARGS $EXTRAFLAGS) ",
+                   $ConfigureLog, "CONFIGURE");
+  # Build the entire tree, capturing the output into $BuildLog
+  if (!$NOCLEAN) {
+      RunAppendingLoggedCommand("($NICE $MAKECMD $MAKEOPTS clean)", $BuildLog, "BUILD CLEAN");
+  }
+  RunAppendingLoggedCommand("(time -p $NICE $MAKECMD $MAKEOPTS)", $BuildLog, "BUILD");
+
+  if (`grep -a '^$MAKECMD\[^:]*: .*Error' $BuildLog | wc -l` + 0 ||
+      `grep -a '^$MAKECMD: \*\*\*.*Stop.' $BuildLog | wc -l` + 0) {
+    return 0;
+  }
+
+  return 1;
+}
+
+# Run the named tests (i.e. "SingleSource" "MultiSource" "External")
+sub TestDirectory {
+  my $SubDir = shift;
+  ChangeDir( "$LLVMTestDir/$SubDir",
+             "Programs Test Subdirectory" ) || return ("", "");
+
+  my $ProgramTestLog = "$Prefix-$SubDir-ProgramTest.txt";
+
+  # Make sure to clean the test results.
+  RunLoggedCommand("$MAKECMD -k $MAKEOPTS $PROGTESTOPTS clean $TESTFLAGS",
+                   $ProgramTestLog, "TEST DIRECTORY $SubDir");
+
+  # Run the programs tests... creating a report.nightly.csv file.
+  my $LLCBetaOpts = "";
+  RunLoggedCommand("$MAKECMD -k $MAKEOPTS $PROGTESTOPTS report.nightly.csv ".
+                   "$TESTFLAGS TEST=nightly",
+                   $ProgramTestLog, "TEST DIRECTORY $SubDir");
+  $LLCBetaOpts = `$MAKECMD print-llcbeta-option`;
+
+  my $ProgramsTable;
+  if (`grep -a '^$MAKECMD\[^:]: .*Error' $ProgramTestLog | wc -l` + 0) {
+    $ProgramsTable="Error running test $SubDir\n";
+    print "ERROR TESTING\n";
+  } elsif (`grep -a '^$MAKECMD\[^:]: .*No rule to make target' $ProgramTestLog | wc -l` + 0) {
+    $ProgramsTable="Makefile error running tests $SubDir!\n";
+    print "ERROR TESTING\n";
+  } else {
+    # Create a list of the tests which were run...
+    system "egrep -a 'TEST-(PASS|FAIL)' < $ProgramTestLog ".
+           "| sort > $Prefix-$SubDir-Tests.txt";
+  }
+  $ProgramsTable = ReadFile "report.nightly.csv";
+
+  ChangeDir( "../../..", "Programs Test Parent Directory" );
+  return ($ProgramsTable, $LLCBetaOpts);
+}
+
+# Run all the nightly tests and return the program tables and the list of tests,
+# passes, fails, and xfails.
+sub RunNightlyTest() {
+  ($SSProgs, $llcbeta_options) = TestDirectory("SingleSource");
+  WriteFile "$Prefix-SingleSource-Performance.txt", $SSProgs;
+  ($MSProgs, $llcbeta_options) = TestDirectory("MultiSource");
+  WriteFile "$Prefix-MultiSource-Performance.txt", $MSProgs;
+  if ( ! $NOEXTERNALS ) {
+    ($ExtProgs, $llcbeta_options) = TestDirectory("External");
+    WriteFile "$Prefix-External-Performance.txt", $ExtProgs;
+    system "cat $Prefix-SingleSource-Tests.txt " .
+               "$Prefix-MultiSource-Tests.txt ".
+               "$Prefix-External-Tests.txt | sort > $Prefix-Tests.txt";
+    system "cat $Prefix-SingleSource-Performance.txt " .
+               "$Prefix-MultiSource-Performance.txt ".
+               "$Prefix-External-Performance.txt | sort > $Prefix-Performance.txt";
+  } else {
+    $ExtProgs = "External TEST STAGE SKIPPED\n";
+    if ( $VERBOSE ) {
+      print "External TEST STAGE SKIPPED\n";
+    }
+    system "cat $Prefix-SingleSource-Tests.txt " .
+               "$Prefix-MultiSource-Tests.txt ".
+               " | sort > $Prefix-Tests.txt";
+    system "cat $Prefix-SingleSource-Performance.txt " .
+               "$Prefix-MultiSource-Performance.txt ".
+               " | sort > $Prefix-Performance.txt";
+  }
+
+  # Compile passes, fails, xfails.
+  my $All = (ReadFile "$Prefix-Tests.txt");
+  my @TestSuiteResultLines = split "\n", $All;
+  my ($Passes, $Fails, $XFails) = "";
+
+  for ($x=0; $x < @TestSuiteResultLines; $x++) {
+    if (@TestSuiteResultLines[$x] =~ m/^PASS:/) {
+      $Passes .= "$TestSuiteResultLines[$x]\n";
+    }
+    elsif (@TestSuiteResultLines[$x] =~ m/^FAIL:/) {
+      $Fails .= "$TestSuiteResultLines[$x]\n";
+    }
+    elsif (@TestSuiteResultLines[$x] =~ m/^XFAIL:/) {
+      $XFails .= "$TestSuiteResultLines[$x]\n";
+    }
+  }
+
+  return ($SSProgs, $MSProgs, $ExtProgs, $All, $Passes, $Fails, $XFails);
+}
+
+##############################################################
+#
+# Initialize filenames
+#
+##############################################################
+
+if (! -d $WebDir) {
+  mkdir $WebDir, 0777 or die "Unable to create web directory: '$WebDir'.";
+  if($VERBOSE){
+    warn "$WebDir did not exist; creating it.\n";
+  }
+}
+
+if ($CONFIG_PATH ne "") {
+  $ConfigMode = 1;
+  $LLVMSrcDir = GetRegex "^(.*)\\s+", `$CONFIG_PATH --src-root`;
+  $LLVMObjDir = GetRegex "^(.*)\\s+", `$CONFIG_PATH --obj-root`;
+  # FIXME: Add llvm-config hook for this?
+  $LLVMTestDir = $LLVMObjDir . "/projects/test-suite";
+} else {
+  $ConfigureLog = "$Prefix-Configure-Log.txt";
+  $BuildLog = "$Prefix-Build-Log.txt";
+  $COLog = "$Prefix-CVS-Log.txt";
+}
+
+if ($VERBOSE) {
+  if ($CONFIG_PATH ne "") {
+    print "INITIALIZED (config mode)\n";
+    print "WebDir    = $WebDir\n";
+    print "Prefix    = $Prefix\n";
+    print "LLVM Src  = $LLVMSrcDir\n";
+    print "LLVM Obj  = $LLVMObjDir\n";
+    print "LLVM Test = $LLVMTestDir\n";
+  } else {
+    print "INITIALIZED\n";
+    print "SVN URL  = $SVNURL\n";
+    print "COLog    = $COLog\n";
+    print "BuildDir = $BuildDir\n";
+    print "WebDir   = $WebDir\n";
+    print "Prefix   = $Prefix\n";
+    print "BuildLog = $BuildLog\n";
+  }
+}
+
+##############################################################
+#
+# The actual NewNightlyTest logic.
+#
+##############################################################
+
+$starttime = `date "+20%y-%m-%d %H:%M:%S"`;
+
+my $BuildError = 0, $BuildStatus = "OK";
+if ($ConfigMode == 0) {
+  if (!$NOCHECKOUT) {
+    CheckoutSource();
+  }
+
+  # Build LLVM.
+  ChangeDir( $LLVMSrcDir , "llvm source directory") ;
+  if ($NOCHECKOUT || $NOBUILD) {
+    $BuildStatus = "Skipped by user";
+  } else {
+    if (!BuildLLVM()) {
+      if( $VERBOSE) { print  "\n***ERROR BUILDING TREE\n\n"; }
+      $BuildError = 1;
+      $BuildStatus = "Error: compilation aborted";
+    }
+  }
+}
+
+# Run the llvm-test tests.
+my ($SingleSourceProgramsTable, $MultiSourceProgramsTable, $ExternalProgramsTable,
+    $all_tests, $passes, $fails, $xfails) = "";
+if (!$NOTEST && !$BuildError) {
+  ($SingleSourceProgramsTable, $MultiSourceProgramsTable, $ExternalProgramsTable,
+   $all_tests, $passes, $fails, $xfails) = RunNightlyTest();
+}
+
+$endtime = `date "+20%y-%m-%d %H:%M:%S"`;
+
+# The last bit of logic is to remove the build and web dirs, after sending data
+# to the server.
+
+##############################################################
+#
+# Accumulate the information to send to the server.
+#
+##############################################################
+
+if ( $VERBOSE ) { print "PREPARING LOGS TO BE SENT TO SERVER\n"; }
+
+if ( ! $NOUNAME ) {
+    $machine_data = "uname: ".`uname -a`.
+        "hardware: ".`uname -m`.
+        "os: ".`uname -sr`.
+        "name: ".`uname -n`.
+        "date: ".`date \"+20%y-%m-%d\"`.
+        "time: ".`date +\"%H:%M:%S\"`;
+} else {
+    $machine_data = "uname: (excluded)\n".
+        "hardware: ".`uname -m`.
+        "os: ".`uname -sr`.
+        "name: $nickname\n".
+        "date: ".`date \"+20%y-%m-%d\"`.
+        "time: ".`date +\"%H:%M:%S\"`;
+}
+
+# Get gcc version.
+my $gcc_version_long = "";
+if ($GCCPATH ne "") {
+  $gcc_version_long = `$GCCPATH/gcc --version`;
+} elsif ($ENV{"CC"}) {
+  $gcc_version_long = `$ENV{"CC"} --version`;
+} else {
+  $gcc_version_long = `gcc --version`;
+}
+my $gcc_version = (split '\n', $gcc_version_long)[0];
+
+# Get llvm-gcc target triple.
+#
+# FIXME: This shouldn't be hardwired to llvm-gcc.
+my $llvmgcc_version_long = "";
+if ($LLVMGCCPATH ne "") {
+  $llvmgcc_version_long = `$LLVMGCCPATH/llvm-gcc -v 2>&1`;
+} else {
+  $llvmgcc_version_long = `llvm-gcc -v 2>&1`;
+}
+(split '\n', $llvmgcc_version_long)[1] =~ /Target: (.+)/;
+my $targetTriple = $1;
+
+# Logs.
+my ($ConfigureLogData, $BuildLogData, $CheckoutLogData) = "";
+if ($ConfigMode == 0) {
+  $ConfigureLogData = ReadFile $ConfigureLog;
+  $BuildLogData = ReadFile $BuildLog;
+  $CheckoutLogData = ReadFile $COLog;
+}
+
+# Checkout info.
+my $CheckoutTime_Wall = GetRegex "^real ([0-9.]+)", $CheckoutLogData;
+my $CheckoutTime_User = GetRegex "^user ([0-9.]+)", $CheckoutLogData;
+my $CheckoutTime_Sys = GetRegex "^sys ([0-9.]+)", $CheckoutLogData;
+my $CheckoutTime_CPU = $CVSCheckoutTime_User + $CVSCheckoutTime_Sys;
+
+# Configure info.
+my $ConfigTimeU = GetRegex "^user ([0-9.]+)", $ConfigureLogData;
+my $ConfigTimeS = GetRegex "^sys ([0-9.]+)", $ConfigureLogData;
+my $ConfigTime  = $ConfigTimeU+$ConfigTimeS;  # ConfigTime = User+System
+my $ConfigWallTime = GetRegex "^real ([0-9.]+)",$ConfigureLogData;
+$ConfigTime=-1 unless $ConfigTime;
+$ConfigWallTime=-1 unless $ConfigWallTime;
+
+# Build info.
+my $BuildTimeU = GetRegex "^user ([0-9.]+)", $BuildLogData;
+my $BuildTimeS = GetRegex "^sys ([0-9.]+)", $BuildLogData;
+my $BuildTime  = $BuildTimeU+$BuildTimeS;  # BuildTime = User+System
+my $BuildWallTime = GetRegex "^real ([0-9.]+)", $BuildLogData;
+$BuildTime=-1 unless $BuildTime;
+$BuildWallTime=-1 unless $BuildWallTime;
+
+if ( $VERBOSE ) { print "SEND THE DATA VIA THE POST REQUEST\n"; }
+
+my %hash_of_data = (
+  'machine_data' => $machine_data,
+  'build_data' => $ConfigureLogData . $BuildLogData,
+  'gcc_version' => $gcc_version,
+  'nickname' => $nickname,
+  'dejagnutime_wall' => "0.0",
+  'dejagnutime_cpu' => "0.0",
+  'cvscheckouttime_wall' => $CheckoutTime_Wall,
+  'cvscheckouttime_cpu' => $CheckoutTime_CPU,
+  'configtime_wall' => $ConfigWallTime,
+  'configtime_cpu'=> $ConfigTime,
+  'buildtime_wall' => $BuildWallTime,
+  'buildtime_cpu' => $BuildTime,
+  'buildstatus' => $BuildStatus,
+  'singlesource_programstable' => $SingleSourceProgramsTable,
+  'multisource_programstable' => $MultiSourceProgramsTable,
+  'externalsource_programstable' => $ExternalProgramsTable,
+  'llcbeta_options' => $llcbeta_options,
+  'passing_tests' => $passes,
+  'expfail_tests' => $xfails,
+  'unexpfail_tests' => $fails,
+  'all_tests' => $all_tests,
+  'dejagnutests_results' => "Dejagnu skipped by user choice.",
+  'dejagnutests_log' => "",
+  'starttime' => $starttime,
+  'endtime' => $endtime,
+  'target_triple' => $targetTriple,
+
+  # Unused, but left around for backwards compatability.
+  'warnings' => "",
+  'cvsusercommitlist' => "",
+  'cvsuserupdatelist' => "",
+  'cvsaddedfiles' => "",
+  'cvsmodifiedfiles' => "",
+  'cvsremovedfiles' => "",
+  'lines_of_code' => "",
+  'cvs_file_count' => 0,
+  'cvs_dir_count' => 0,
+  'warnings_removed' => "",
+  'warnings_added' => "",
+  'new_tests' => "",
+  'removed_tests' => "",
+  'o_file_sizes' => "",
+  'a_file_sizes' => ""
+);
+
+# Write out the "...-sentdata.txt" file.
+WriteSentData \%hash_of_data;
+
+if ($SUBMIT || !($SUBMITAUX eq "")) {
+  my $response = SendData $SUBMITSERVER,$SUBMITSCRIPT,\%hash_of_data;
+  if( $VERBOSE) { print "============================\n$response"; }
+} else {
+  print "============================\n";
+  foreach $x(keys %hash_of_data){
+      print "$x  => $hash_of_data{$x}\n";
+  }
+}
+
+##############################################################
+#
+# Remove the source tree...
+#
+##############################################################
+system ( "$NICE rm -rf $BuildDir")
+  if (!$NOCHECKOUT and !$NOREMOVE and !$NOREMOVEATEND);
+system ( "$NICE rm -rf $WebDir")
+  if (!$NOCHECKOUT and !$NOREMOVE and !$NOREMOVERESULTS);
diff --git a/src/LLVM/utils/NightlyTest.gnuplot b/src/LLVM/utils/NightlyTest.gnuplot
new file mode 100644
index 0000000..95c39d2
--- /dev/null
+++ b/src/LLVM/utils/NightlyTest.gnuplot
@@ -0,0 +1,214 @@
+set terminal png

+

+##------- Plot small Date vs LOC ----

+set output "running_loc.png"

+set xlabel "Date" 

+set ylabel "Lines of Code"

+set xdata time

+set timefmt "%Y-%m-%d-%H:%M:%S:"

+set format x "%b %d, %Y"

+

+set size .75,.75

+set xtics rotate

+set xlabel 0,-1

+plot "running_loc.txt" using 1:2 title '' with lines, \

+     "running_loc.txt" using 1:2 title "Date vs. Lines of Code" with lines

+

+##------- Plot large Date vs LOC ----

+set size 1.5,1.5

+set xtics norotate

+set xlabel 0,0

+set output "running_loc_large.png"

+plot "running_loc.txt" using 1:2 title '', \

+     "running_loc.txt" using 1:2 title "Date vs. Lines of Code" with lines

+

+

+# Delete all labels...

+set nolabel

+

+##------- Olden CBE performance ----

+

+set size .75,.75

+set xtics rotate

+set xlabel 0,-1

+set output "running_Olden_cbe_time.png"

+set ylabel "CBE compiled execution time (s)"

+plot "running_Olden_cbe_time.txt" u 1:2 t '' with lines, \

+     "running_Olden_cbe_time.txt" u 1:2 t "bh" with lines, \

+     "running_Olden_cbe_time.txt" u 1:3 t "em3d" with lines, \

+     "running_Olden_cbe_time.txt" u 1:4 t "mst" with lines, \

+     "running_Olden_cbe_time.txt" u 1:5 t "power" with lines, \

+     "running_Olden_cbe_time.txt" u 1:6 t "tsp" with lines, \

+     "running_Olden_cbe_time.txt" u 1:7 t "bisort" with lines, \

+     "running_Olden_cbe_time.txt" u 1:8 t "health" with lines, \

+     "running_Olden_cbe_time.txt" u 1:9 t "perimeter" with lines, \

+     "running_Olden_cbe_time.txt" u 1:10 t "treeadd" with lines, \

+     "running_Olden_cbe_time.txt" u 1:11 t "voronoi" \

+   with lines

+

+set size 1.5,1.5

+set xtics norotate

+set xlabel 0,0

+set output "running_Olden_cbe_time_large.png"

+plot "running_Olden_cbe_time.txt" u 1:2 t '' with lines, \

+     "running_Olden_cbe_time.txt" u 1:2 t "bh" with lines, \

+     "running_Olden_cbe_time.txt" u 1:3 t "em3d" with lines, \

+     "running_Olden_cbe_time.txt" u 1:4 t "mst" with lines, \

+     "running_Olden_cbe_time.txt" u 1:5 t "power" with lines, \

+     "running_Olden_cbe_time.txt" u 1:6 t "tsp" with lines, \

+     "running_Olden_cbe_time.txt" u 1:7 t "bisort" with lines, \

+     "running_Olden_cbe_time.txt" u 1:8 t "health" with lines, \

+     "running_Olden_cbe_time.txt" u 1:9 t "perimeter" with lines, \

+     "running_Olden_cbe_time.txt" u 1:10 t "treeadd" with lines, \

+     "running_Olden_cbe_time.txt" u 1:11 t "voronoi" \

+   with lines

+

+##------- Olden JIT performance ----

+

+set size .75,.75

+set xtics rotate

+set xlabel 0,-1

+set output "running_Olden_jit_time.png"

+set ylabel "JIT execution time (s)"

+plot "running_Olden_jit_time.txt" u 1:2 t '' with lines, \

+     "running_Olden_jit_time.txt" u 1:2 t "bh" with lines, \

+     "running_Olden_jit_time.txt" u 1:3 t "em3d" with lines, \

+     "running_Olden_jit_time.txt" u 1:4 t "mst" with lines, \

+     "running_Olden_jit_time.txt" u 1:5 t "power" with lines, \

+     "running_Olden_jit_time.txt" u 1:6 t "tsp" with lines, \

+     "running_Olden_jit_time.txt" u 1:7 t "bisort" with lines, \

+     "running_Olden_jit_time.txt" u 1:8 t "health" with lines, \

+     "running_Olden_jit_time.txt" u 1:9 t "perimeter" with lines, \

+     "running_Olden_jit_time.txt" u 1:10 t "treeadd" with lines, \

+     "running_Olden_jit_time.txt" u 1:11 t "voronoi" \

+   with lines

+

+set size 1.5,1.5

+set xtics norotate

+set xlabel 0,0

+set output "running_Olden_jit_time_large.png"

+plot "running_Olden_jit_time.txt" u 1:2 t '' with lines, \

+     "running_Olden_jit_time.txt" u 1:2 t "bh" with lines, \

+     "running_Olden_jit_time.txt" u 1:3 t "em3d" with lines, \

+     "running_Olden_jit_time.txt" u 1:4 t "mst" with lines, \

+     "running_Olden_jit_time.txt" u 1:5 t "power" with lines, \

+     "running_Olden_jit_time.txt" u 1:6 t "tsp" with lines, \

+     "running_Olden_jit_time.txt" u 1:7 t "bisort" with lines, \

+     "running_Olden_jit_time.txt" u 1:8 t "health" with lines, \

+     "running_Olden_jit_time.txt" u 1:9 t "perimeter" with lines, \

+     "running_Olden_jit_time.txt" u 1:10 t "treeadd" with lines, \

+     "running_Olden_jit_time.txt" u 1:11 t "voronoi" \

+   with lines

+

+##------- Olden LLC performance ----

+

+set size .75,.75

+set xtics rotate

+set xlabel 0,-1

+set output "running_Olden_llc_time.png"

+set ylabel "LLC compiled execution time (s)"

+plot "running_Olden_llc_time.txt" u 1:2 t '' with lines, \

+     "running_Olden_llc_time.txt" u 1:2 t "bh" with lines, \

+     "running_Olden_llc_time.txt" u 1:3 t "em3d" with lines, \

+     "running_Olden_llc_time.txt" u 1:4 t "mst" with lines, \

+     "running_Olden_llc_time.txt" u 1:5 t "power" with lines, \

+     "running_Olden_llc_time.txt" u 1:6 t "tsp" with lines, \

+     "running_Olden_llc_time.txt" u 1:7 t "bisort" with lines, \

+     "running_Olden_llc_time.txt" u 1:8 t "health" with lines, \

+     "running_Olden_llc_time.txt" u 1:9 t "perimeter" with lines, \

+     "running_Olden_llc_time.txt" u 1:10 t "treeadd" with lines, \

+     "running_Olden_llc_time.txt" u 1:11 t "voronoi" \

+   with lines

+

+set size 1.5,1.5

+set xtics norotate

+set xlabel 0,0

+set output "running_Olden_llc_time_large.png"

+plot "running_Olden_llc_time.txt" u 1:2 t '' with lines, \

+     "running_Olden_llc_time.txt" u 1:2 t "bh" with lines, \

+     "running_Olden_llc_time.txt" u 1:3 t "em3d" with lines, \

+     "running_Olden_llc_time.txt" u 1:4 t "mst" with lines, \

+     "running_Olden_llc_time.txt" u 1:5 t "power" with lines, \

+     "running_Olden_llc_time.txt" u 1:6 t "tsp" with lines, \

+     "running_Olden_llc_time.txt" u 1:7 t "bisort" with lines, \

+     "running_Olden_llc_time.txt" u 1:8 t "health" with lines, \

+     "running_Olden_llc_time.txt" u 1:9 t "perimeter" with lines, \

+     "running_Olden_llc_time.txt" u 1:10 t "treeadd" with lines, \

+     "running_Olden_llc_time.txt" u 1:11 t "voronoi" \

+   with lines

+

+

+##------- Olden optimizer time ----

+

+set size .75,.75

+set xtics rotate

+set xlabel 0,-1

+set output "running_Olden_opt_time.png"

+set ylabel "Time to run the optimizer (s)"

+plot "running_Olden_opt_time.txt" u 1:2 t '' with lines, \

+     "running_Olden_opt_time.txt" u 1:2 t "bh" with lines, \

+     "running_Olden_opt_time.txt" u 1:3 t "em3d" with lines, \

+     "running_Olden_opt_time.txt" u 1:4 t "mst" with lines, \

+     "running_Olden_opt_time.txt" u 1:5 t "power" with lines, \

+     "running_Olden_opt_time.txt" u 1:6 t "tsp" with lines, \

+     "running_Olden_opt_time.txt" u 1:7 t "bisort" with lines, \

+     "running_Olden_opt_time.txt" u 1:8 t "health" with lines, \

+     "running_Olden_opt_time.txt" u 1:9 t "perimeter" with lines, \

+     "running_Olden_opt_time.txt" u 1:10 t "treeadd" with lines, \

+     "running_Olden_opt_time.txt" u 1:11 t "voronoi" \

+   with lines

+

+set size 1.5,1.5

+set xtics norotate

+set xlabel 0,0

+set output "running_Olden_opt_time_large.png"

+plot "running_Olden_opt_time.txt" u 1:2 t '' with lines, \

+     "running_Olden_opt_time.txt" u 1:2 t "bh" with lines, \

+     "running_Olden_opt_time.txt" u 1:3 t "em3d" with lines, \

+     "running_Olden_opt_time.txt" u 1:4 t "mst" with lines, \

+     "running_Olden_opt_time.txt" u 1:5 t "power" with lines, \

+     "running_Olden_opt_time.txt" u 1:6 t "tsp" with lines, \

+     "running_Olden_opt_time.txt" u 1:7 t "bisort" with lines, \

+     "running_Olden_opt_time.txt" u 1:8 t "health" with lines, \

+     "running_Olden_opt_time.txt" u 1:9 t "perimeter" with lines, \

+     "running_Olden_opt_time.txt" u 1:10 t "treeadd" with lines, \

+     "running_Olden_opt_time.txt" u 1:11 t "voronoi" \

+   with lines

+

+

+##------- Bytecode size ----

+

+set size .75,.75

+set xtics rotate

+set xlabel 0,-1

+set output "running_Olden_bytecode.png"

+set ylabel "Program bytecode size (bytes)"

+plot "running_Olden_bytecode.txt" u 1:2 t '' with lines, \

+     "running_Olden_bytecode.txt" u 1:2 t "bh" with lines, \

+     "running_Olden_bytecode.txt" u 1:3 t "em3d" with lines, \

+     "running_Olden_bytecode.txt" u 1:4 t "mst" with lines, \

+     "running_Olden_bytecode.txt" u 1:5 t "power" with lines, \

+     "running_Olden_bytecode.txt" u 1:6 t "tsp" with lines, \

+     "running_Olden_bytecode.txt" u 1:7 t "bisort" with lines, \

+     "running_Olden_bytecode.txt" u 1:8 t "health" with lines, \

+     "running_Olden_bytecode.txt" u 1:9 t "perimeter" with lines, \

+     "running_Olden_bytecode.txt" u 1:10 t "treeadd" with lines, \

+     "running_Olden_bytecode.txt" u 1:11 t "voronoi" \

+   with lines

+

+set size 1.5,1.5

+set xtics norotate

+set xlabel 0,0

+set output "running_Olden_bytecode_large.png"

+plot "running_Olden_bytecode.txt" u 1:2 t '' with lines, \

+     "running_Olden_bytecode.txt" u 1:2 t "bh" with lines, \

+     "running_Olden_bytecode.txt" u 1:3 t "em3d" with lines, \

+     "running_Olden_bytecode.txt" u 1:4 t "mst" with lines, \

+     "running_Olden_bytecode.txt" u 1:5 t "power" with lines, \

+     "running_Olden_bytecode.txt" u 1:6 t "tsp" with lines, \

+     "running_Olden_bytecode.txt" u 1:7 t "bisort" with lines, \

+     "running_Olden_bytecode.txt" u 1:8 t "health" with lines, \

+     "running_Olden_bytecode.txt" u 1:9 t "perimeter" with lines, \

+     "running_Olden_bytecode.txt" u 1:10 t "treeadd" with lines, \

+     "running_Olden_bytecode.txt" u 1:11 t "voronoi" \

+   with lines

diff --git a/src/LLVM/utils/NightlyTestTemplate.html b/src/LLVM/utils/NightlyTestTemplate.html
new file mode 100644
index 0000000..c38bb2e
--- /dev/null
+++ b/src/LLVM/utils/NightlyTestTemplate.html
@@ -0,0 +1,244 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><title>LLVM Test Results for $DateString</title></head>
+
+<body bgcolor=white>
+<center><font size=+3 face=Verdana><b>LLVM Test Results for $DateString</b></font></center>
+<hr height=1>
+
+<table width=100%>
+<tr><td valign=top align=center>
+
+<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#000000"> 
+<table border="0" cellpadding="5" cellspacing="0"><tr><td bgcolor="#DDAA77">
+<font size=+1><b>Sections:</b></font><br>
+</td></tr><tr><td bgcolor="#FFCC99" align=center>
+<a href="#Overview">Overview</a><br>
+<a href="#Changes">Changes</a><br>
+<a href="#Dejagnu">Dejagnu Tests</a><br>
+<a href="#Trends">Trends</a><br>
+<a href="#Programs">Programs</a><br>
+</td></tr></table></td></tr></table>
+
+<p>
+<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#000000"> 
+<table border="0" cellpadding="5" cellspacing="0"><tr><td bgcolor="#DDAA77"
+<font size=+1><b>Previous:</b></font><br>
+</td></tr><tr><td bgcolor="#FFCC99">
+  $PrevDaysList
+</td></tr></table></td></tr></table>
+<p>
+
+<font size=+1><b>Back to:</b></font><br>
+<a href="http://llvm.org/testresults/">Test&nbsp;Results</a><br>
+<a href="http://llvm.org/">LLVM&nbsp;Page</a><p>
+
+</td><td valign=top>
+
+<center>
+<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#000000"> 
+<table border="0" cellpadding="10" cellspacing="0"><tr><td bgcolor="#DDAA77"
+<font size=+2 face=Verdana><b><a name="Overview">Today's Test Results Overview</font></b>
+</td></tr></table></td></tr></table></center><p>
+
+<!-- Running LOC graph -->
+<table align=right>
+<tr><td>
+<a href="running_loc_large.png"
+   ><img border=0 width=480 height=360 src="running_loc.png"></a>
+</td></tr>
+<tr><td align=center>Lines Of Code over Time<br>
+<font size=-1><a href="running_loc_large.png">Click for larger view</a></font>
+</td></tr>
+</table>
+
+<h2>Nightly Test Overview:</h2>
+<ul>
+  <li>Start: <b>$TestStartTime</b></li>
+  <li>Finish: <b>$TestFinishTime</b></li>
+  <li>Platform: <b>$TestPlatform</b></li>
+</ul>
+<h2>CVS Tree Overview:</h2>
+<ul>
+<li><a href="$DATE-CVS-Log.txt">CVS Checkout Log</a>
+<ul>
+    <b>$NumDirsInCVS</b> dirs, <b>$NumFilesInCVS</b> files, <b>$LOC</b>
+    lines of code, checked out in <b>$CVSCheckoutTime</b> seconds<br></ul>
+<li><a href="$DATE-Build-Log.txt">Compilation Log</a>
+<table>
+<tr><td><b>Item</b></td><td><b>CPU Time</b></td><td><b>Wall Clock</b></td></tr>
+<tr><td>Configure CVS Tree</td><td>$ConfigTime</td><td>$ConfigWallTime</td></tr>
+<tr><td>Build CVS Tree</td><td>$BuildTime</td><td>$BuildWallTime</td></tr>
+<tr><td>Run Dejagnu Tests</td><td>$DejagnuTime</td><td>$DejagnuWallTime</td></tr>
+</table></li>
+<li>Number of object files compiled: <b>$NumObjects</b></li>
+<li>Number of libraries linked: <b>$NumLibraries</b></li>
+<li>Number of executables linked:<b> $NumExecutables</b></li>
+<li>Build Status: $BuildStatus</li>
+</ul>
+
+<h2>Warnings during the build:</h2>
+$WarningsList
+
+<br><br><center>
+<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#000000"> 
+<table border="0" cellpadding="10" cellspacing="0"><tr><td bgcolor="#DDAA77"
+<font size=+2 face=Verdana><b><a name="Changes">Changes from Yesterday</font></b>
+</td></tr></table></td></tr></table></center><p>
+
+<h2>Changes to CVS:</h2>
+<ul>
+<li>Users who committed to CVS: <b>$UserCommitList</b>
+<li>Users who updated from CVS: <b>$UserUpdateList</b>
+<li>Added Files:    $AddedFilesList
+<li>Modified Files: $ModifiedFilesList
+<li>Removed Files:  $RemovedFilesList
+</ul><p>
+
+<h2>Changes to Warnings:</h2>
+<p>Warnings Added:</p>
+$WarningsAdded
+<p>Warnings Removed:</p>
+$WarningsRemoved
+
+<h2>Changes in the test suite:</h2>
+<ul>
+<li>New Tests: $TestsAdded
+<li>Removed Tests: $TestsRemoved
+<li>Newly passing tests: $TestsFixed
+<li>Newly failing tests: $TestsBroken
+</ul>
+</td></tr></tbody></table>
+
+
+<br/><br/><center>
+<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#000000"> 
+<table border="0" cellpadding="10" cellspacing="0"><tr><td bgcolor="#DDAA77"
+<font size=+2 face=Verdana><b><a name="Dejagnu">Dejagnu Test Results</font></b>
+</td></tr></table></td></tr></table></center>
+<br/>
+$DejagnuTestResults
+<p>A complete log of testing <a href="$DATE-Dejagnu-testrun.log">Feature and Regression</a> is available for further analysis.</p>
+
+<br><br><center>
+<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#000000"> 
+<table border="0" cellpadding="10" cellspacing="0"><tr><td bgcolor="#DDAA77"
+<font size=+2 face=Verdana><b><a name="Trends">Changes Over Time</font></b>
+</td></tr></table></td></tr></table></center><p>
+
+
+Here are some charts showing how the LLVM optimizer and code generators are
+changing over time.  For now we use the Olden benchmark suite to measure this,
+but eventually we will switch to using SPEC CPU2000.  All programs are run with
+"LARGE_PROBLEM_SIZE" enabled.  Click on any of the charts to get a larger
+version.<p>
+
+<h2>Compilation Measurements:</h2>
+
+<table border="0" align=center>
+<tr>
+<td width=50% align=center>
+<a href="running_Olden_bytecode_large.png"><img width=480 height=360 border=0 src="running_Olden_bytecode.png"></a><br>
+Size of LLVM bytecode files
+</td>
+<td width=50% align=center>
+<a href="running_Olden_opt_time_large.png"><img width=480 height=360 border=0 src="running_Olden_opt_time.png"></a><br>
+Time to run the LLVM optimizer on each program
+</td></tr>
+</table>
+
+<h2>Program Execution Measurements:</h2>
+
+<table border="0" align=center>
+<tr>
+<td width=50% align=center>
+<a href="running_Olden_cbe_time_large.png"><img width=480 height=360 border=0 src="running_Olden_cbe_time.png"></a><br>
+Execution time for CBE generated executable
+</td>
+<td width=50% align=center>
+<a href="running_Olden_llc_time_large.png"><img width=480 height=360 border=0 src="running_Olden_llc_time.png"></a><br>
+Execution time for the LLC generated executable
+</td></tr>
+
+<tr>
+<td align=center>
+<a href="running_Olden_jit_time_large.png"><img width=480 height=360 border=0 src="running_Olden_jit_time.png"></a><br>
+Execution time for program in the JIT
+</td>
+<td></td></tr>
+</table>
+
+
+
+
+<br><br><center>
+<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#000000"> 
+<table border="0" cellpadding="10" cellspacing="0"><tr><td bgcolor="#DDAA77"
+<font size=+2 face=Verdana><b><a name="Programs">Program Tests</font></b>
+</td></tr></table></td></tr></table></center><p>
+
+This section tests LLVM on a variety of programs in the test suite.  This
+includes benchmark suites like the Olden, McCat, Ptrdist, and SPEC benchmarks as
+well as a few random programs with test inputs.  This section is meant to track
+how stable LLVM is as a whole. A failure in the execution of any test is marked
+with an asterisk: `*'. The columns of the tables are:<p>
+
+<ol>
+<li><a name="Program">Program</a> - The name of the program for that row.</li>
+<li><a name="GCCAS">GCCAS</a> - Time to run LLVM optimizers on the program.</li>
+<li><a name="Bytecode">Bytecode</a> - The size of the bytecode for the
+    program</li>
+<li><a name="Instrs">Instrs</a> - The number of LLVM instructions in the
+    compiled bytecode</li>
+<li><a name="LLC<br>compile">LLC compile</a> - The time taken compile with
+    LLC (the static backend)</li>
+<li><a name="JIT<br>codegen">JIT codegen</a> - The amount of time spent in the
+    JIT itself, instead of executing the program.</li>
+<li><a name="Machine<br>code">Machine code</a> - The number of bytes of machine
+    code generated by the JIT.</li>
+<li><a name="GCC">GCC</a> - The time taken to execute the program when compiled
+    with GCC -O2.</li>
+<li><a name="CBE">CBE</a> - The time taken to execute the program after
+    compilation through the C backend, compiled with -O2.</li>
+<li><a name="LLC">LLC</a> - How long does the program generated by the static
+    backend LLC take to execute </li>
+<li><a name="JIT">JIT</a> - The amount of time spent running the
+    program with the JIT; this includes the code generation phase (listed above)
+    and actually running the program.</li>
+<li><a name="GCC/LLC">GCC/LLC</a> - The speed-up of the LLC output vs the native 
+    GCC output: greater than 1 is a speedup, less than 1 is a slowdown.</li>
+<li><a name="GCC/CBE">GCC/CBE</a> - The speed-up of the CBE output vs the native 
+    GCC output: greater than 1 is a speedup, less than 1 is a slowdown.</li>
+<li><a name="LLC-BETA">LLC-BETA</a> - How long does the program generated by the static
+    backend LLC take to execute the program, when compiled with new experimental 
+    features.  This is temporary, for tuning.</li>
+</ol><p>
+
+A complete log of testing 
+<a href="$DATE-SingleSource-ProgramTest.txt.gz">SingleSource</a>, 
+<a href="$DATE-MultiSource-ProgramTest.txt.gz">MultiSource</a>, and
+<a href="$DATE-External-ProgramTest.txt.gz">External</a> programs are
+available for further analysis.
+
+<h2>Programs/External</h2>
+
+<center>
+<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#000000"> 
+$ExternalProgramsTable
+</td></tr></table></center>
+
+<h2>Programs/MultiSource</h2>
+
+<center>
+<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#000000"> 
+$MultiSourceProgramsTable
+</td></tr></table></center>
+
+<h2>Programs/SingleSource</h2>
+
+<center>
+<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#000000"> 
+$SingleSourceProgramsTable
+</td></tr></table></center>
+
+</td></tr></html>
+
diff --git a/src/LLVM/utils/OldenDataRecover.pl b/src/LLVM/utils/OldenDataRecover.pl
new file mode 100644
index 0000000..7678394
--- /dev/null
+++ b/src/LLVM/utils/OldenDataRecover.pl
@@ -0,0 +1,37 @@
+#this script is intended to help recover the running graphs when
+#the nightly tester decides to eat them.
+
+#zgrep -E "(=========)|(TEST-RESULT-llc-time)" *-Olden-tests.txt* |perl this > file
+#zgrep -E "(=========)|(TEST-RESULT-compile.*bc)" *-Olden-tests.tx* |perl this >file
+
+while (<>) {
+  if (/(\d*-\d*-\d*)-.*=========.*\/(.*)\' Program/) {
+#    print "$1 $2\n";
+    $curP = $2;
+    $curD = $1;
+    $dates{$1} = 1;
+  } elsif (/(\d*-\d*-\d*)-.*TEST-RESULT-.*: program (\d*\.\d*)/) {
+#    print "$1 $2\n";
+    if ($curD eq $1) {
+      $$data{$curD}{$curP} = $2;
+    }
+  } elsif (/(\d*-\d*-\d*)-.*TEST-RESULT-.*: (\d*)/) {
+#    print "$1 $2\n";
+    if ($curD eq $1) {
+      $$data{$curD}{$curP} = $2;
+    }
+  }
+}
+@progs = ("bh", "em3d", "mst", "power", "tsp", "bisort", "health", "perimeter", "treeadd", "voronoi");
+
+foreach $date (sort keys %dates) {
+  print "$date: ";
+  foreach $prog (@progs) {
+    if ($$data{$date}{$prog}) {
+      print " $$data{$date}{$prog}";
+    } else {
+      print " 0";
+    }
+  }
+  print "\n";
+}
diff --git a/src/LLVM/utils/PerfectShuffle/Makefile b/src/LLVM/utils/PerfectShuffle/Makefile
new file mode 100644
index 0000000..28709fe
--- /dev/null
+++ b/src/LLVM/utils/PerfectShuffle/Makefile
@@ -0,0 +1,18 @@
+##===- utils/PerfectShuffle/Makefile -----------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+TOOLNAME = llvm-PerfectShuffle
+NO_INSTALL = 1
+
+# This tool has no plugins, optimize startup time.
+TOOL_NO_EXPORTS = 1
+
+include $(LEVEL)/Makefile.common
+
diff --git a/src/LLVM/utils/PerfectShuffle/PerfectShuffle.cpp b/src/LLVM/utils/PerfectShuffle/PerfectShuffle.cpp
new file mode 100644
index 0000000..b94a7d3
--- /dev/null
+++ b/src/LLVM/utils/PerfectShuffle/PerfectShuffle.cpp
@@ -0,0 +1,571 @@
+//===-- PerfectShuffle.cpp - Perfect Shuffle Generator --------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file computes an optimal sequence of instructions for doing all shuffles
+// of two 4-element vectors.  With a release build and when configured to emit
+// an altivec instruction table, this takes about 30s to run on a 2.7Ghz
+// PowerPC G5.
+//
+//===----------------------------------------------------------------------===//
+
+#include <iostream>
+#include <vector>
+#include <cassert>
+#include <cstdlib>
+struct Operator;
+
+// Masks are 4-nibble hex numbers.  Values 0-7 in any nibble means that it takes
+// an element from that value of the input vectors.  A value of 8 means the
+// entry is undefined.
+
+// Mask manipulation functions.
+static inline unsigned short MakeMask(unsigned V0, unsigned V1,
+                                      unsigned V2, unsigned V3) {
+  return (V0 << (3*4)) | (V1 << (2*4)) | (V2 << (1*4)) | (V3 << (0*4));
+}
+
+/// getMaskElt - Return element N of the specified mask.
+static unsigned getMaskElt(unsigned Mask, unsigned Elt) {
+  return (Mask >> ((3-Elt)*4)) & 0xF;
+}
+
+static unsigned setMaskElt(unsigned Mask, unsigned Elt, unsigned NewVal) {
+  unsigned FieldShift = ((3-Elt)*4);
+  return (Mask & ~(0xF << FieldShift)) | (NewVal << FieldShift);
+}
+
+// Reject elements where the values are 9-15.
+static bool isValidMask(unsigned short Mask) {
+  unsigned short UndefBits = Mask & 0x8888;
+  return (Mask & ((UndefBits >> 1)|(UndefBits>>2)|(UndefBits>>3))) == 0;
+}
+
+/// hasUndefElements - Return true if any of the elements in the mask are undefs
+///
+static bool hasUndefElements(unsigned short Mask) {
+  return (Mask & 0x8888) != 0;
+}
+
+/// isOnlyLHSMask - Return true if this mask only refers to its LHS, not
+/// including undef values..
+static bool isOnlyLHSMask(unsigned short Mask) {
+  return (Mask & 0x4444) == 0;
+}
+
+/// getLHSOnlyMask - Given a mask that refers to its LHS and RHS, modify it to
+/// refer to the LHS only (for when one argument value is passed into the same
+/// function twice).
+#if 0
+static unsigned short getLHSOnlyMask(unsigned short Mask) {
+  return Mask & 0xBBBB;  // Keep only LHS and Undefs.
+}
+#endif
+
+/// getCompressedMask - Turn a 16-bit uncompressed mask (where each elt uses 4
+/// bits) into a compressed 13-bit mask, where each elt is multiplied by 9.
+static unsigned getCompressedMask(unsigned short Mask) {
+  return getMaskElt(Mask, 0)*9*9*9 + getMaskElt(Mask, 1)*9*9 +
+         getMaskElt(Mask, 2)*9     + getMaskElt(Mask, 3);
+}
+
+static void PrintMask(unsigned i, std::ostream &OS) {
+  OS << "<" << (char)(getMaskElt(i, 0) == 8 ? 'u' : ('0'+getMaskElt(i, 0)))
+     << "," << (char)(getMaskElt(i, 1) == 8 ? 'u' : ('0'+getMaskElt(i, 1)))
+     << "," << (char)(getMaskElt(i, 2) == 8 ? 'u' : ('0'+getMaskElt(i, 2)))
+     << "," << (char)(getMaskElt(i, 3) == 8 ? 'u' : ('0'+getMaskElt(i, 3)))
+     << ">";
+}
+
+/// ShuffleVal - This represents a shufflevector operation.
+struct ShuffleVal {
+  unsigned Cost;  // Number of instrs used to generate this value.
+  Operator *Op;   // The Operation used to generate this value.
+  unsigned short Arg0, Arg1;  // Input operands for this value.
+
+  ShuffleVal() : Cost(1000000) {}
+};
+
+
+/// ShufTab - This is the actual shuffle table that we are trying to generate.
+///
+static ShuffleVal ShufTab[65536];
+
+/// TheOperators - All of the operators that this target supports.
+static std::vector<Operator*> TheOperators;
+
+/// Operator - This is a vector operation that is available for use.
+struct Operator {
+  unsigned short ShuffleMask;
+  unsigned short OpNum;
+  const char *Name;
+  unsigned Cost;
+
+  Operator(unsigned short shufflemask, const char *name, unsigned opnum,
+           unsigned cost = 1)
+    : ShuffleMask(shufflemask), OpNum(opnum), Name(name), Cost(cost) {
+    TheOperators.push_back(this);
+  }
+  ~Operator() {
+    assert(TheOperators.back() == this);
+    TheOperators.pop_back();
+  }
+
+  bool isOnlyLHSOperator() const {
+    return isOnlyLHSMask(ShuffleMask);
+  }
+
+  const char *getName() const { return Name; }
+  unsigned getCost() const { return Cost; }
+
+  unsigned short getTransformedMask(unsigned short LHSMask, unsigned RHSMask) {
+    // Extract the elements from LHSMask and RHSMask, as appropriate.
+    unsigned Result = 0;
+    for (unsigned i = 0; i != 4; ++i) {
+      unsigned SrcElt = (ShuffleMask >> (4*i)) & 0xF;
+      unsigned ResElt;
+      if (SrcElt < 4)
+        ResElt = getMaskElt(LHSMask, SrcElt);
+      else if (SrcElt < 8)
+        ResElt = getMaskElt(RHSMask, SrcElt-4);
+      else {
+        assert(SrcElt == 8 && "Bad src elt!");
+        ResElt = 8;
+      }
+      Result |= ResElt << (4*i);
+    }
+    return Result;
+  }
+};
+
+static const char *getZeroCostOpName(unsigned short Op) {
+  if (ShufTab[Op].Arg0 == 0x0123)
+    return "LHS";
+  else if (ShufTab[Op].Arg0 == 0x4567)
+    return "RHS";
+  else {
+    assert(0 && "bad zero cost operation");
+    abort();
+  }
+}
+
+static void PrintOperation(unsigned ValNo, unsigned short Vals[]) {
+  unsigned short ThisOp = Vals[ValNo];
+  std::cerr << "t" << ValNo;
+  PrintMask(ThisOp, std::cerr);
+  std::cerr << " = " << ShufTab[ThisOp].Op->getName() << "(";
+
+  if (ShufTab[ShufTab[ThisOp].Arg0].Cost == 0) {
+    std::cerr << getZeroCostOpName(ShufTab[ThisOp].Arg0);
+    PrintMask(ShufTab[ThisOp].Arg0, std::cerr);
+  } else {
+    // Figure out what tmp # it is.
+    for (unsigned i = 0; ; ++i)
+      if (Vals[i] == ShufTab[ThisOp].Arg0) {
+        std::cerr << "t" << i;
+        break;
+      }
+  }
+
+  if (!ShufTab[Vals[ValNo]].Op->isOnlyLHSOperator()) {
+    std::cerr << ", ";
+    if (ShufTab[ShufTab[ThisOp].Arg1].Cost == 0) {
+      std::cerr << getZeroCostOpName(ShufTab[ThisOp].Arg1);
+      PrintMask(ShufTab[ThisOp].Arg1, std::cerr);
+    } else {
+      // Figure out what tmp # it is.
+      for (unsigned i = 0; ; ++i)
+        if (Vals[i] == ShufTab[ThisOp].Arg1) {
+          std::cerr << "t" << i;
+          break;
+        }
+    }
+  }
+  std::cerr << ")  ";
+}
+
+static unsigned getNumEntered() {
+  unsigned Count = 0;
+  for (unsigned i = 0; i != 65536; ++i)
+    Count += ShufTab[i].Cost < 100;
+  return Count;
+}
+
+static void EvaluateOps(unsigned short Elt, unsigned short Vals[],
+                        unsigned &NumVals) {
+  if (ShufTab[Elt].Cost == 0) return;
+
+  // If this value has already been evaluated, it is free.  FIXME: match undefs.
+  for (unsigned i = 0, e = NumVals; i != e; ++i)
+    if (Vals[i] == Elt) return;
+
+  // Otherwise, get the operands of the value, then add it.
+  unsigned Arg0 = ShufTab[Elt].Arg0, Arg1 = ShufTab[Elt].Arg1;
+  if (ShufTab[Arg0].Cost)
+    EvaluateOps(Arg0, Vals, NumVals);
+  if (Arg0 != Arg1 && ShufTab[Arg1].Cost)
+    EvaluateOps(Arg1, Vals, NumVals);
+
+  Vals[NumVals++] = Elt;
+}
+
+
+int main() {
+  // Seed the table with accesses to the LHS and RHS.
+  ShufTab[0x0123].Cost = 0;
+  ShufTab[0x0123].Op = 0;
+  ShufTab[0x0123].Arg0 = 0x0123;
+  ShufTab[0x4567].Cost = 0;
+  ShufTab[0x4567].Op = 0;
+  ShufTab[0x4567].Arg0 = 0x4567;
+
+  // Seed the first-level of shuffles, shuffles whose inputs are the input to
+  // the vectorshuffle operation.
+  bool MadeChange = true;
+  unsigned OpCount = 0;
+  while (MadeChange) {
+    MadeChange = false;
+    ++OpCount;
+    std::cerr << "Starting iteration #" << OpCount << " with "
+              << getNumEntered() << " entries established.\n";
+
+    // Scan the table for two reasons: First, compute the maximum cost of any
+    // operation left in the table.  Second, make sure that values with undefs
+    // have the cheapest alternative that they match.
+    unsigned MaxCost = ShufTab[0].Cost;
+    for (unsigned i = 1; i != 0x8889; ++i) {
+      if (!isValidMask(i)) continue;
+      if (ShufTab[i].Cost > MaxCost)
+        MaxCost = ShufTab[i].Cost;
+
+      // If this value has an undef, make it be computed the cheapest possible
+      // way of any of the things that it matches.
+      if (hasUndefElements(i)) {
+        // This code is a little bit tricky, so here's the idea: consider some
+        // permutation, like 7u4u.  To compute the lowest cost for 7u4u, we
+        // need to take the minimum cost of all of 7[0-8]4[0-8], 81 entries.  If
+        // there are 3 undefs, the number rises to 729 entries we have to scan,
+        // and for the 4 undef case, we have to scan the whole table.
+        //
+        // Instead of doing this huge amount of scanning, we process the table
+        // entries *in order*, and use the fact that 'u' is 8, larger than any
+        // valid index.  Given an entry like 7u4u then, we only need to scan
+        // 7[0-7]4u - 8 entries.  We can get away with this, because we already
+        // know that each of 704u, 714u, 724u, etc contain the minimum value of
+        // all of the 704[0-8], 714[0-8] and 724[0-8] entries respectively.
+        unsigned UndefIdx;
+        if (i & 0x8000)
+          UndefIdx = 0;
+        else if (i & 0x0800)
+          UndefIdx = 1;
+        else if (i & 0x0080)
+          UndefIdx = 2;
+        else if (i & 0x0008)
+          UndefIdx = 3;
+        else
+          abort();
+
+        unsigned MinVal  = i;
+        unsigned MinCost = ShufTab[i].Cost;
+
+        // Scan the 8 entries.
+        for (unsigned j = 0; j != 8; ++j) {
+          unsigned NewElt = setMaskElt(i, UndefIdx, j);
+          if (ShufTab[NewElt].Cost < MinCost) {
+            MinCost = ShufTab[NewElt].Cost;
+            MinVal = NewElt;
+          }
+        }
+
+        // If we found something cheaper than what was here before, use it.
+        if (i != MinVal) {
+          MadeChange = true;
+          ShufTab[i] = ShufTab[MinVal];
+        }
+      }
+    }
+
+    for (unsigned LHS = 0; LHS != 0x8889; ++LHS) {
+      if (!isValidMask(LHS)) continue;
+      if (ShufTab[LHS].Cost > 1000) continue;
+
+      // If nothing involving this operand could possibly be cheaper than what
+      // we already have, don't consider it.
+      if (ShufTab[LHS].Cost + 1 >= MaxCost)
+        continue;
+
+      for (unsigned opnum = 0, e = TheOperators.size(); opnum != e; ++opnum) {
+        Operator *Op = TheOperators[opnum];
+
+        // Evaluate op(LHS,LHS)
+        unsigned ResultMask = Op->getTransformedMask(LHS, LHS);
+
+        unsigned Cost = ShufTab[LHS].Cost + Op->getCost();
+        if (Cost < ShufTab[ResultMask].Cost) {
+          ShufTab[ResultMask].Cost = Cost;
+          ShufTab[ResultMask].Op = Op;
+          ShufTab[ResultMask].Arg0 = LHS;
+          ShufTab[ResultMask].Arg1 = LHS;
+          MadeChange = true;
+        }
+
+        // If this is a two input instruction, include the op(x,y) cases.  If
+        // this is a one input instruction, skip this.
+        if (Op->isOnlyLHSOperator()) continue;
+
+        for (unsigned RHS = 0; RHS != 0x8889; ++RHS) {
+          if (!isValidMask(RHS)) continue;
+          if (ShufTab[RHS].Cost > 1000) continue;
+
+          // If nothing involving this operand could possibly be cheaper than
+          // what we already have, don't consider it.
+          if (ShufTab[RHS].Cost + 1 >= MaxCost)
+            continue;
+
+
+          // Evaluate op(LHS,RHS)
+          unsigned ResultMask = Op->getTransformedMask(LHS, RHS);
+
+          if (ShufTab[ResultMask].Cost <= OpCount ||
+              ShufTab[ResultMask].Cost <= ShufTab[LHS].Cost ||
+              ShufTab[ResultMask].Cost <= ShufTab[RHS].Cost)
+            continue;
+
+          // Figure out the cost to evaluate this, knowing that CSE's only need
+          // to be evaluated once.
+          unsigned short Vals[30];
+          unsigned NumVals = 0;
+          EvaluateOps(LHS, Vals, NumVals);
+          EvaluateOps(RHS, Vals, NumVals);
+
+          unsigned Cost = NumVals + Op->getCost();
+          if (Cost < ShufTab[ResultMask].Cost) {
+            ShufTab[ResultMask].Cost = Cost;
+            ShufTab[ResultMask].Op = Op;
+            ShufTab[ResultMask].Arg0 = LHS;
+            ShufTab[ResultMask].Arg1 = RHS;
+            MadeChange = true;
+          }
+        }
+      }
+    }
+  }
+
+  std::cerr << "Finished Table has " << getNumEntered()
+            << " entries established.\n";
+
+  unsigned CostArray[10] = { 0 };
+
+  // Compute a cost histogram.
+  for (unsigned i = 0; i != 65536; ++i) {
+    if (!isValidMask(i)) continue;
+    if (ShufTab[i].Cost > 9)
+      ++CostArray[9];
+    else
+      ++CostArray[ShufTab[i].Cost];
+  }
+
+  for (unsigned i = 0; i != 9; ++i)
+    if (CostArray[i])
+      std::cout << "// " << CostArray[i] << " entries have cost " << i << "\n";
+  if (CostArray[9])
+    std::cout << "// " << CostArray[9] << " entries have higher cost!\n";
+
+
+  // Build up the table to emit.
+  std::cout << "\n// This table is 6561*4 = 26244 bytes in size.\n";
+  std::cout << "static const unsigned PerfectShuffleTable[6561+1] = {\n";
+
+  for (unsigned i = 0; i != 0x8889; ++i) {
+    if (!isValidMask(i)) continue;
+
+    // CostSat - The cost of this operation saturated to two bits.
+    unsigned CostSat = ShufTab[i].Cost;
+    if (CostSat > 4) CostSat = 4;
+    if (CostSat == 0) CostSat = 1;
+    --CostSat;  // Cost is now between 0-3.
+
+    unsigned OpNum = ShufTab[i].Op ? ShufTab[i].Op->OpNum : 0;
+    assert(OpNum < 16 && "Too few bits to encode operation!");
+
+    unsigned LHS = getCompressedMask(ShufTab[i].Arg0);
+    unsigned RHS = getCompressedMask(ShufTab[i].Arg1);
+
+    // Encode this as 2 bits of saturated cost, 4 bits of opcodes, 13 bits of
+    // LHS, and 13 bits of RHS = 32 bits.
+    unsigned Val = (CostSat << 30) | (OpNum << 26) | (LHS << 13) | RHS;
+
+    std::cout << "  " << Val << "U,\t// ";
+    PrintMask(i, std::cout);
+    std::cout << ": Cost " << ShufTab[i].Cost;
+    std::cout << " " << (ShufTab[i].Op ? ShufTab[i].Op->getName() : "copy");
+    std::cout << " ";
+    if (ShufTab[ShufTab[i].Arg0].Cost == 0) {
+      std::cout << getZeroCostOpName(ShufTab[i].Arg0);
+    } else {
+      PrintMask(ShufTab[i].Arg0, std::cout);
+    }
+
+    if (ShufTab[i].Op && !ShufTab[i].Op->isOnlyLHSOperator()) {
+      std::cout << ", ";
+      if (ShufTab[ShufTab[i].Arg1].Cost == 0) {
+        std::cout << getZeroCostOpName(ShufTab[i].Arg1);
+      } else {
+        PrintMask(ShufTab[i].Arg1, std::cout);
+      }
+    }
+    std::cout << "\n";
+  }
+  std::cout << "  0\n};\n";
+
+  if (0) {
+    // Print out the table.
+    for (unsigned i = 0; i != 0x8889; ++i) {
+      if (!isValidMask(i)) continue;
+      if (ShufTab[i].Cost < 1000) {
+        PrintMask(i, std::cerr);
+        std::cerr << " - Cost " << ShufTab[i].Cost << " - ";
+
+        unsigned short Vals[30];
+        unsigned NumVals = 0;
+        EvaluateOps(i, Vals, NumVals);
+
+        for (unsigned j = 0, e = NumVals; j != e; ++j)
+          PrintOperation(j, Vals);
+        std::cerr << "\n";
+      }
+    }
+  }
+}
+
+
+#ifdef GENERATE_ALTIVEC
+
+///===---------------------------------------------------------------------===//
+/// The altivec instruction definitions.  This is the altivec-specific part of
+/// this file.
+///===---------------------------------------------------------------------===//
+
+// Note that the opcode numbers here must match those in the PPC backend.
+enum {
+  OP_COPY = 0,   // Copy, used for things like <u,u,u,3> to say it is <0,1,2,3>
+  OP_VMRGHW,
+  OP_VMRGLW,
+  OP_VSPLTISW0,
+  OP_VSPLTISW1,
+  OP_VSPLTISW2,
+  OP_VSPLTISW3,
+  OP_VSLDOI4,
+  OP_VSLDOI8,
+  OP_VSLDOI12
+};
+
+struct vmrghw : public Operator {
+  vmrghw() : Operator(0x0415, "vmrghw", OP_VMRGHW) {}
+} the_vmrghw;
+
+struct vmrglw : public Operator {
+  vmrglw() : Operator(0x2637, "vmrglw", OP_VMRGLW) {}
+} the_vmrglw;
+
+template<unsigned Elt>
+struct vspltisw : public Operator {
+  vspltisw(const char *N, unsigned Opc)
+    : Operator(MakeMask(Elt, Elt, Elt, Elt), N, Opc) {}
+};
+
+vspltisw<0> the_vspltisw0("vspltisw0", OP_VSPLTISW0);
+vspltisw<1> the_vspltisw1("vspltisw1", OP_VSPLTISW1);
+vspltisw<2> the_vspltisw2("vspltisw2", OP_VSPLTISW2);
+vspltisw<3> the_vspltisw3("vspltisw3", OP_VSPLTISW3);
+
+template<unsigned N>
+struct vsldoi : public Operator {
+  vsldoi(const char *Name, unsigned Opc)
+    : Operator(MakeMask(N&7, (N+1)&7, (N+2)&7, (N+3)&7), Name, Opc) {
+  }
+};
+
+vsldoi<1> the_vsldoi1("vsldoi4" , OP_VSLDOI4);
+vsldoi<2> the_vsldoi2("vsldoi8" , OP_VSLDOI8);
+vsldoi<3> the_vsldoi3("vsldoi12", OP_VSLDOI12);
+
+#endif
+
+#define GENERATE_NEON
+
+#ifdef GENERATE_NEON
+enum {
+  OP_COPY = 0,   // Copy, used for things like <u,u,u,3> to say it is <0,1,2,3>
+  OP_VREV,
+  OP_VDUP0,
+  OP_VDUP1,
+  OP_VDUP2,
+  OP_VDUP3,
+  OP_VEXT1,
+  OP_VEXT2,
+  OP_VEXT3,
+  OP_VUZPL, // VUZP, left result
+  OP_VUZPR, // VUZP, right result
+  OP_VZIPL, // VZIP, left result
+  OP_VZIPR, // VZIP, right result
+  OP_VTRNL, // VTRN, left result
+  OP_VTRNR  // VTRN, right result
+};
+
+struct vrev : public Operator {
+  vrev() : Operator(0x1032, "vrev", OP_VREV) {}
+} the_vrev;
+
+template<unsigned Elt>
+struct vdup : public Operator {
+  vdup(const char *N, unsigned Opc)
+    : Operator(MakeMask(Elt, Elt, Elt, Elt), N, Opc) {}
+};
+
+vdup<0> the_vdup0("vdup0", OP_VDUP0);
+vdup<1> the_vdup1("vdup1", OP_VDUP1);
+vdup<2> the_vdup2("vdup2", OP_VDUP2);
+vdup<3> the_vdup3("vdup3", OP_VDUP3);
+
+template<unsigned N>
+struct vext : public Operator {
+  vext(const char *Name, unsigned Opc)
+    : Operator(MakeMask(N&7, (N+1)&7, (N+2)&7, (N+3)&7), Name, Opc) {
+  }
+};
+
+vext<1> the_vext1("vext1", OP_VEXT1);
+vext<2> the_vext2("vext2", OP_VEXT2);
+vext<3> the_vext3("vext3", OP_VEXT3);
+
+struct vuzpl : public Operator {
+  vuzpl() : Operator(0x0246, "vuzpl", OP_VUZPL, 2) {}
+} the_vuzpl;
+
+struct vuzpr : public Operator {
+  vuzpr() : Operator(0x1357, "vuzpr", OP_VUZPR, 2) {}
+} the_vuzpr;
+
+struct vzipl : public Operator {
+  vzipl() : Operator(0x0415, "vzipl", OP_VZIPL, 2) {}
+} the_vzipl;
+
+struct vzipr : public Operator {
+  vzipr() : Operator(0x2637, "vzipr", OP_VZIPR, 2) {}
+} the_vzipr;
+
+struct vtrnl : public Operator {
+  vtrnl() : Operator(0x0426, "vtrnl", OP_VTRNL, 2) {}
+} the_vtrnl;
+
+struct vtrnr : public Operator {
+  vtrnr() : Operator(0x1537, "vtrnr", OP_VTRNR, 2) {}
+} the_vtrnr;
+
+#endif
diff --git a/src/LLVM/utils/RegressionFinder.pl b/src/LLVM/utils/RegressionFinder.pl
new file mode 100644
index 0000000..86b0777
--- /dev/null
+++ b/src/LLVM/utils/RegressionFinder.pl
@@ -0,0 +1,186 @@
+#! /usr/bin/perl
+# Script to find regressions by binary-searching a time interval in the
+# CVS tree.  Written by Brian Gaeke on 2-Mar-2004.
+#
+
+require 5.6.0;  # NOTE: This script not tested with earlier versions.
+use Getopt::Std;
+use POSIX;
+use Time::Local;
+use IO::Handle;
+
+sub usage {
+    print STDERR <<END;
+findRegression [-I] -w WTIME -d DTIME -t TOOLS -c SCRIPT
+
+The -w, -d, -t, and -c options are required.
+Run findRegression in the top level of an LLVM tree.
+WTIME is a time when you are sure the regression does NOT exist ("Works").
+DTIME is a time when you are sure the regression DOES exist ("Doesntwork").
+WTIME and DTIME are both in the format: "YYYY/MM/DD HH:MM".
+-I means run builds at WTIME and DTIME first to make sure.
+TOOLS is a comma separated list of tools to rebuild before running SCRIPT.
+SCRIPT exits 1 if the regression is present in TOOLS; 0 otherwise.
+END
+    exit 1;
+}
+
+sub timeAsSeconds {
+    my ($timestr) = @_;
+
+    if ( $timestr =~ /(\d\d\d\d)\/(\d\d)\/(\d\d) (\d\d):(\d\d)/ ) {
+        my ( $year, $mon, $mday, $hour, $min ) = ( $1, $2, $3, $4, $5 );
+        return timegm( 0, $min, $hour, $mday, $mon - 1, $year );
+    }
+    else {
+        die "** Can't parse date + time: $timestr\n";
+    }
+}
+
+sub timeAsString {
+    my ($secs) = @_;
+    return strftime( "%Y/%m/%d %H:%M", gmtime($secs) );
+}
+
+sub run {
+    my ($cmdline) = @_;
+    print LOG "** Running: $cmdline\n";
+	return system($cmdline);
+}
+
+sub buildLibrariesAndTools {
+    run("sh /home/vadve/gaeke/scripts/run-configure");
+    run("$MAKE -C lib/Support");
+    run("$MAKE -C utils");
+    run("$MAKE -C lib");
+    foreach my $tool (@TOOLS) { run("$MAKE -C tools/$tool"); }
+}
+
+sub contains {
+    my ( $file, $regex ) = @_;
+    local (*FILE);
+    open( FILE, "<$file" ) or die "** can't read $file: $!\n";
+    while (<FILE>) {
+        if (/$regex/) {
+            close FILE;
+            return 1;
+        }
+    }
+    close FILE;
+    return 0;
+}
+
+sub updateSources {
+    my ($time) = @_;
+    my $inst = "include/llvm/Instruction.h";
+    unlink($inst);
+    run( "cvs update -D'" . timeAsString($time) . "'" );
+    if ( !contains( $inst, 'class Instruction.*Annotable' ) ) {
+        run("patch -F100 -p0 < makeInstructionAnnotable.patch");
+    }
+}
+
+sub regressionPresentAt {
+    my ($time) = @_;
+
+    updateSources($time);
+    buildLibrariesAndTools();
+    my $rc = run($SCRIPT);
+    if ($rc) {
+        print LOG "** Found that regression was PRESENT at "
+          . timeAsString($time) . "\n";
+        return 1;
+    }
+    else {
+        print LOG "** Found that regression was ABSENT at "
+          . timeAsString($time) . "\n";
+        return 0;
+    }
+}
+
+sub regressionAbsentAt {
+    my ($time) = @_;
+    return !regressionPresentAt($time);
+}
+
+sub closeTo {
+    my ( $time1, $time2 ) = @_;
+    return abs( $time1 - $time2 ) < 600;    # 10 minutes seems reasonable.
+}
+
+sub halfWayPoint {
+    my ( $time1, $time2 ) = @_;
+    my $halfSpan = int( abs( $time1 - $time2 ) / 2 );
+    if ( $time1 < $time2 ) {
+        return $time1 + $halfSpan;
+    }
+    else {
+        return $time2 + $halfSpan;
+    }
+}
+
+sub checkBoundaryConditions {
+    print LOG "** Checking for presence of regression at ", timeAsString($DTIME),
+      "\n";
+    if ( !regressionPresentAt($DTIME) ) {
+        die ( "** Can't help you; $SCRIPT says regression absent at dtime: "
+              . timeAsString($DTIME)
+              . "\n" );
+    }
+    print LOG "** Checking for absence of regression at ", timeAsString($WTIME),
+      "\n";
+    if ( !regressionAbsentAt($WTIME) ) {
+        die ( "** Can't help you; $SCRIPT says regression present at wtime: "
+              . timeAsString($WTIME)
+              . "\n" );
+    }
+}
+
+##############################################################################
+
+# Set up log files
+open (STDERR, ">&STDOUT") || die "** Can't redirect std.err: $!\n";
+autoflush STDOUT 1;
+autoflush STDERR 1;
+open (LOG, ">RegFinder.log") || die "** can't write RegFinder.log: $!\n";
+autoflush LOG 1;
+# Check command line arguments and environment variables
+getopts('Iw:d:t:c:');
+if ( !( $opt_w && $opt_d && $opt_t && $opt_c ) ) {
+    usage;
+}
+$MAKE  = $ENV{'MAKE'};
+$MAKE  = 'gmake' unless $MAKE;
+$WTIME = timeAsSeconds($opt_w);
+print LOG "** Assuming worked at ", timeAsString($WTIME), "\n";
+$DTIME = timeAsSeconds($opt_d);
+print LOG "** Assuming didn't work at ", timeAsString($DTIME), "\n";
+$opt_t =~ s/\s*//g;
+$SCRIPT = $opt_c;
+die "** $SCRIPT is not executable or not found\n" unless -x $SCRIPT;
+print LOG "** Checking for the regression using $SCRIPT\n";
+@TOOLS = split ( /,/, $opt_t );
+print LOG (
+    "** Going to rebuild: ",
+    ( join ", ", @TOOLS ),
+    " before each $SCRIPT run\n"
+);
+if ($opt_I) { checkBoundaryConditions(); }
+# do the dirty work:
+while ( !closeTo( $DTIME, $WTIME ) ) {
+    my $halfPt = halfWayPoint( $DTIME, $WTIME );
+    print LOG "** Checking whether regression is present at ",
+      timeAsString($halfPt), "\n";
+    if ( regressionPresentAt($halfPt) ) {
+        $DTIME = $halfPt;
+    }
+    else {
+        $WTIME = $halfPt;
+    }
+}
+# Tell them what we found
+print LOG "** Narrowed it down to:\n";
+print LOG "** Worked at: ",       timeAsString($WTIME), "\n";
+print LOG "** Did not work at: ", timeAsString($DTIME), "\n";
+close LOG;
+exit 0;
diff --git a/src/LLVM/utils/TableGen/ARMDecoderEmitter.cpp b/src/LLVM/utils/TableGen/ARMDecoderEmitter.cpp
new file mode 100644
index 0000000..8d4f6cd
--- /dev/null
+++ b/src/LLVM/utils/TableGen/ARMDecoderEmitter.cpp
@@ -0,0 +1,1878 @@
+//===------------ ARMDecoderEmitter.cpp - Decoder Generator ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is part of the ARM Disassembler.
+// It contains the tablegen backend that emits the decoder functions for ARM and
+// Thumb.  The disassembler core includes the auto-generated file, invokes the
+// decoder functions, and builds up the MCInst based on the decoded Opcode.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "arm-decoder-emitter"
+
+#include "ARMDecoderEmitter.h"
+#include "CodeGenTarget.h"
+#include "Record.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <vector>
+#include <map>
+#include <string>
+
+using namespace llvm;
+
+/////////////////////////////////////////////////////
+//                                                 //
+//  Enums and Utilities for ARM Instruction Format //
+//                                                 //
+/////////////////////////////////////////////////////
+
+#define ARM_FORMATS                   \
+  ENTRY(ARM_FORMAT_PSEUDO,         0) \
+  ENTRY(ARM_FORMAT_MULFRM,         1) \
+  ENTRY(ARM_FORMAT_BRFRM,          2) \
+  ENTRY(ARM_FORMAT_BRMISCFRM,      3) \
+  ENTRY(ARM_FORMAT_DPFRM,          4) \
+  ENTRY(ARM_FORMAT_DPSOREGFRM,     5) \
+  ENTRY(ARM_FORMAT_LDFRM,          6) \
+  ENTRY(ARM_FORMAT_STFRM,          7) \
+  ENTRY(ARM_FORMAT_LDMISCFRM,      8) \
+  ENTRY(ARM_FORMAT_STMISCFRM,      9) \
+  ENTRY(ARM_FORMAT_LDSTMULFRM,    10) \
+  ENTRY(ARM_FORMAT_LDSTEXFRM,     11) \
+  ENTRY(ARM_FORMAT_ARITHMISCFRM,  12) \
+  ENTRY(ARM_FORMAT_SATFRM,        13) \
+  ENTRY(ARM_FORMAT_EXTFRM,        14) \
+  ENTRY(ARM_FORMAT_VFPUNARYFRM,   15) \
+  ENTRY(ARM_FORMAT_VFPBINARYFRM,  16) \
+  ENTRY(ARM_FORMAT_VFPCONV1FRM,   17) \
+  ENTRY(ARM_FORMAT_VFPCONV2FRM,   18) \
+  ENTRY(ARM_FORMAT_VFPCONV3FRM,   19) \
+  ENTRY(ARM_FORMAT_VFPCONV4FRM,   20) \
+  ENTRY(ARM_FORMAT_VFPCONV5FRM,   21) \
+  ENTRY(ARM_FORMAT_VFPLDSTFRM,    22) \
+  ENTRY(ARM_FORMAT_VFPLDSTMULFRM, 23) \
+  ENTRY(ARM_FORMAT_VFPMISCFRM,    24) \
+  ENTRY(ARM_FORMAT_THUMBFRM,      25) \
+  ENTRY(ARM_FORMAT_MISCFRM,       26) \
+  ENTRY(ARM_FORMAT_NEONGETLNFRM,  27) \
+  ENTRY(ARM_FORMAT_NEONSETLNFRM,  28) \
+  ENTRY(ARM_FORMAT_NEONDUPFRM,    29) \
+  ENTRY(ARM_FORMAT_NLdSt,         30) \
+  ENTRY(ARM_FORMAT_N1RegModImm,   31) \
+  ENTRY(ARM_FORMAT_N2Reg,         32) \
+  ENTRY(ARM_FORMAT_NVCVT,         33) \
+  ENTRY(ARM_FORMAT_NVecDupLn,     34) \
+  ENTRY(ARM_FORMAT_N2RegVecShL,   35) \
+  ENTRY(ARM_FORMAT_N2RegVecShR,   36) \
+  ENTRY(ARM_FORMAT_N3Reg,         37) \
+  ENTRY(ARM_FORMAT_N3RegVecSh,    38) \
+  ENTRY(ARM_FORMAT_NVecExtract,   39) \
+  ENTRY(ARM_FORMAT_NVecMulScalar, 40) \
+  ENTRY(ARM_FORMAT_NVTBL,         41)
+
+// ARM instruction format specifies the encoding used by the instruction.
+#define ENTRY(n, v) n = v,
+typedef enum {
+  ARM_FORMATS
+  ARM_FORMAT_NA
+} ARMFormat;
+#undef ENTRY
+
+// Converts enum to const char*.
+static const char *stringForARMFormat(ARMFormat form) {
+#define ENTRY(n, v) case n: return #n;
+  switch(form) {
+    ARM_FORMATS
+  case ARM_FORMAT_NA:
+  default:
+    return "";
+  }
+#undef ENTRY
+}
+
+enum {
+  IndexModeNone = 0,
+  IndexModePre  = 1,
+  IndexModePost = 2,
+  IndexModeUpd  = 3
+};
+
+/////////////////////////
+//                     //
+//  Utility functions  //
+//                     //
+/////////////////////////
+
+/// byteFromBitsInit - Return the byte value from a BitsInit.
+/// Called from getByteField().
+static uint8_t byteFromBitsInit(BitsInit &init) {
+  int width = init.getNumBits();
+
+  assert(width <= 8 && "Field is too large for uint8_t!");
+
+  int index;
+  uint8_t mask = 0x01;
+
+  uint8_t ret = 0;
+
+  for (index = 0; index < width; index++) {
+    if (static_cast<BitInit*>(init.getBit(index))->getValue())
+      ret |= mask;
+
+    mask <<= 1;
+  }
+
+  return ret;
+}
+
+static uint8_t getByteField(const Record &def, const char *str) {
+  BitsInit *bits = def.getValueAsBitsInit(str);
+  return byteFromBitsInit(*bits);
+}
+
+static BitsInit &getBitsField(const Record &def, const char *str) {
+  BitsInit *bits = def.getValueAsBitsInit(str);
+  return *bits;
+}
+
+/// sameStringExceptSuffix - Return true if the two strings differ only in RHS's
+/// suffix.  ("VST4d8", "VST4d8_UPD", "_UPD") as input returns true.
+static
+bool sameStringExceptSuffix(const StringRef LHS, const StringRef RHS,
+                            const StringRef Suffix) {
+
+  if (RHS.startswith(LHS) && RHS.endswith(Suffix))
+    return RHS.size() == LHS.size() + Suffix.size();
+
+  return false;
+}
+
+/// thumbInstruction - Determine whether we have a Thumb instruction.
+/// See also ARMInstrFormats.td.
+static bool thumbInstruction(uint8_t Form) {
+  return Form == ARM_FORMAT_THUMBFRM;
+}
+
+// The set (BIT_TRUE, BIT_FALSE, BIT_UNSET) represents a ternary logic system
+// for a bit value.
+//
+// BIT_UNFILTERED is used as the init value for a filter position.  It is used
+// only for filter processings.
+typedef enum {
+  BIT_TRUE,      // '1'
+  BIT_FALSE,     // '0'
+  BIT_UNSET,     // '?'
+  BIT_UNFILTERED // unfiltered
+} bit_value_t;
+
+static bool ValueSet(bit_value_t V) {
+  return (V == BIT_TRUE || V == BIT_FALSE);
+}
+static bool ValueNotSet(bit_value_t V) {
+  return (V == BIT_UNSET);
+}
+static int Value(bit_value_t V) {
+  return ValueNotSet(V) ? -1 : (V == BIT_FALSE ? 0 : 1);
+}
+static bit_value_t bitFromBits(BitsInit &bits, unsigned index) {
+  if (BitInit *bit = dynamic_cast<BitInit*>(bits.getBit(index)))
+    return bit->getValue() ? BIT_TRUE : BIT_FALSE;
+
+  // The bit is uninitialized.
+  return BIT_UNSET;
+}
+// Prints the bit value for each position.
+static void dumpBits(raw_ostream &o, BitsInit &bits) {
+  unsigned index;
+
+  for (index = bits.getNumBits(); index > 0; index--) {
+    switch (bitFromBits(bits, index - 1)) {
+    case BIT_TRUE:
+      o << "1";
+      break;
+    case BIT_FALSE:
+      o << "0";
+      break;
+    case BIT_UNSET:
+      o << "_";
+      break;
+    default:
+      assert(0 && "unexpected return value from bitFromBits");
+    }
+  }
+}
+
+// Enums for the available target names.
+typedef enum {
+  TARGET_ARM = 0,
+  TARGET_THUMB
+} TARGET_NAME_t;
+
+// FIXME: Possibly auto-detected?
+#define BIT_WIDTH 32
+
+// Forward declaration.
+class FilterChooser;
+
+// Representation of the instruction to work on.
+typedef bit_value_t insn_t[BIT_WIDTH];
+
+/// Filter - Filter works with FilterChooser to produce the decoding tree for
+/// the ISA.
+///
+/// It is useful to think of a Filter as governing the switch stmts of the
+/// decoding tree in a certain level.  Each case stmt delegates to an inferior
+/// FilterChooser to decide what further decoding logic to employ, or in another
+/// words, what other remaining bits to look at.  The FilterChooser eventually
+/// chooses a best Filter to do its job.
+///
+/// This recursive scheme ends when the number of Opcodes assigned to the
+/// FilterChooser becomes 1 or if there is a conflict.  A conflict happens when
+/// the Filter/FilterChooser combo does not know how to distinguish among the
+/// Opcodes assigned.
+///
+/// An example of a conflcit is 
+///
+/// Conflict:
+///                     111101000.00........00010000....
+///                     111101000.00........0001........
+///                     1111010...00........0001........
+///                     1111010...00....................
+///                     1111010.........................
+///                     1111............................
+///                     ................................
+///     VST4q8a         111101000_00________00010000____
+///     VST4q8b         111101000_00________00010000____
+///
+/// The Debug output shows the path that the decoding tree follows to reach the
+/// the conclusion that there is a conflict.  VST4q8a is a vst4 to double-spaced
+/// even registers, while VST4q8b is a vst4 to double-spaced odd regsisters.
+///
+/// The encoding info in the .td files does not specify this meta information,
+/// which could have been used by the decoder to resolve the conflict.  The
+/// decoder could try to decode the even/odd register numbering and assign to
+/// VST4q8a or VST4q8b, but for the time being, the decoder chooses the "a"
+/// version and return the Opcode since the two have the same Asm format string.
+class Filter {
+protected:
+  FilterChooser *Owner; // points to the FilterChooser who owns this filter
+  unsigned StartBit; // the starting bit position
+  unsigned NumBits; // number of bits to filter
+  bool Mixed; // a mixed region contains both set and unset bits
+
+  // Map of well-known segment value to the set of uid's with that value. 
+  std::map<uint64_t, std::vector<unsigned> > FilteredInstructions;
+
+  // Set of uid's with non-constant segment values.
+  std::vector<unsigned> VariableInstructions;
+
+  // Map of well-known segment value to its delegate.
+  std::map<unsigned, FilterChooser*> FilterChooserMap;
+
+  // Number of instructions which fall under FilteredInstructions category.
+  unsigned NumFiltered;
+
+  // Keeps track of the last opcode in the filtered bucket.
+  unsigned LastOpcFiltered;
+
+  // Number of instructions which fall under VariableInstructions category.
+  unsigned NumVariable;
+
+public:
+  unsigned getNumFiltered() { return NumFiltered; }
+  unsigned getNumVariable() { return NumVariable; }
+  unsigned getSingletonOpc() {
+    assert(NumFiltered == 1);
+    return LastOpcFiltered;
+  }
+  // Return the filter chooser for the group of instructions without constant
+  // segment values.
+  FilterChooser &getVariableFC() {
+    assert(NumFiltered == 1);
+    assert(FilterChooserMap.size() == 1);
+    return *(FilterChooserMap.find((unsigned)-1)->second);
+  }
+
+  Filter(const Filter &f);
+  Filter(FilterChooser &owner, unsigned startBit, unsigned numBits, bool mixed);
+
+  ~Filter();
+
+  // Divides the decoding task into sub tasks and delegates them to the
+  // inferior FilterChooser's.
+  //
+  // A special case arises when there's only one entry in the filtered
+  // instructions.  In order to unambiguously decode the singleton, we need to
+  // match the remaining undecoded encoding bits against the singleton.
+  void recurse();
+
+  // Emit code to decode instructions given a segment or segments of bits.
+  void emit(raw_ostream &o, unsigned &Indentation);
+
+  // Returns the number of fanout produced by the filter.  More fanout implies
+  // the filter distinguishes more categories of instructions.
+  unsigned usefulness() const;
+}; // End of class Filter
+
+// These are states of our finite state machines used in FilterChooser's
+// filterProcessor() which produces the filter candidates to use.
+typedef enum {
+  ATTR_NONE,
+  ATTR_FILTERED,
+  ATTR_ALL_SET,
+  ATTR_ALL_UNSET,
+  ATTR_MIXED
+} bitAttr_t;
+
+/// FilterChooser - FilterChooser chooses the best filter among a set of Filters
+/// in order to perform the decoding of instructions at the current level.
+///
+/// Decoding proceeds from the top down.  Based on the well-known encoding bits
+/// of instructions available, FilterChooser builds up the possible Filters that
+/// can further the task of decoding by distinguishing among the remaining
+/// candidate instructions.
+///
+/// Once a filter has been chosen, it is called upon to divide the decoding task
+/// into sub-tasks and delegates them to its inferior FilterChoosers for further
+/// processings.
+///
+/// It is useful to think of a Filter as governing the switch stmts of the
+/// decoding tree.  And each case is delegated to an inferior FilterChooser to
+/// decide what further remaining bits to look at.
+class FilterChooser {
+  static TARGET_NAME_t TargetName;
+
+protected:
+  friend class Filter;
+
+  // Vector of codegen instructions to choose our filter.
+  const std::vector<const CodeGenInstruction*> &AllInstructions;
+
+  // Vector of uid's for this filter chooser to work on.
+  const std::vector<unsigned> Opcodes;
+
+  // Vector of candidate filters.
+  std::vector<Filter> Filters;
+
+  // Array of bit values passed down from our parent.
+  // Set to all BIT_UNFILTERED's for Parent == NULL.
+  bit_value_t FilterBitValues[BIT_WIDTH];
+
+  // Links to the FilterChooser above us in the decoding tree.
+  FilterChooser *Parent;
+  
+  // Index of the best filter from Filters.
+  int BestIndex;
+
+public:
+  static void setTargetName(TARGET_NAME_t tn) { TargetName = tn; }
+
+  FilterChooser(const FilterChooser &FC) :
+      AllInstructions(FC.AllInstructions), Opcodes(FC.Opcodes),
+      Filters(FC.Filters), Parent(FC.Parent), BestIndex(FC.BestIndex) {
+    memcpy(FilterBitValues, FC.FilterBitValues, sizeof(FilterBitValues));
+  }
+
+  FilterChooser(const std::vector<const CodeGenInstruction*> &Insts,
+                const std::vector<unsigned> &IDs) :
+      AllInstructions(Insts), Opcodes(IDs), Filters(), Parent(NULL),
+      BestIndex(-1) {
+    for (unsigned i = 0; i < BIT_WIDTH; ++i)
+      FilterBitValues[i] = BIT_UNFILTERED;
+
+    doFilter();
+  }
+
+  FilterChooser(const std::vector<const CodeGenInstruction*> &Insts,
+                const std::vector<unsigned> &IDs,
+                bit_value_t (&ParentFilterBitValues)[BIT_WIDTH],
+                FilterChooser &parent) :
+      AllInstructions(Insts), Opcodes(IDs), Filters(), Parent(&parent),
+      BestIndex(-1) {
+    for (unsigned i = 0; i < BIT_WIDTH; ++i)
+      FilterBitValues[i] = ParentFilterBitValues[i];
+
+    doFilter();
+  }
+
+  // The top level filter chooser has NULL as its parent.
+  bool isTopLevel() { return Parent == NULL; }
+
+  // This provides an opportunity for target specific code emission.
+  void emitTopHook(raw_ostream &o);
+
+  // Emit the top level typedef and decodeInstruction() function.
+  void emitTop(raw_ostream &o, unsigned &Indentation);
+
+  // This provides an opportunity for target specific code emission after
+  // emitTop().
+  void emitBot(raw_ostream &o, unsigned &Indentation);
+
+protected:
+  // Populates the insn given the uid.
+  void insnWithID(insn_t &Insn, unsigned Opcode) const {
+    BitsInit &Bits = getBitsField(*AllInstructions[Opcode]->TheDef, "Inst");
+
+    for (unsigned i = 0; i < BIT_WIDTH; ++i)
+      Insn[i] = bitFromBits(Bits, i);
+
+    // Set Inst{21} to 1 (wback) when IndexModeBits == IndexModeUpd.
+    if (getByteField(*AllInstructions[Opcode]->TheDef, "IndexModeBits")
+        == IndexModeUpd)
+      Insn[21] = BIT_TRUE;
+  }
+
+  // Returns the record name.
+  const std::string &nameWithID(unsigned Opcode) const {
+    return AllInstructions[Opcode]->TheDef->getName();
+  }
+
+  // Populates the field of the insn given the start position and the number of
+  // consecutive bits to scan for.
+  //
+  // Returns false if there exists any uninitialized bit value in the range.
+  // Returns true, otherwise.
+  bool fieldFromInsn(uint64_t &Field, insn_t &Insn, unsigned StartBit,
+      unsigned NumBits) const;
+
+  /// dumpFilterArray - dumpFilterArray prints out debugging info for the given
+  /// filter array as a series of chars.
+  void dumpFilterArray(raw_ostream &o, bit_value_t (&filter)[BIT_WIDTH]);
+
+  /// dumpStack - dumpStack traverses the filter chooser chain and calls
+  /// dumpFilterArray on each filter chooser up to the top level one.
+  void dumpStack(raw_ostream &o, const char *prefix);
+
+  Filter &bestFilter() {
+    assert(BestIndex != -1 && "BestIndex not set");
+    return Filters[BestIndex];
+  }
+
+  // Called from Filter::recurse() when singleton exists.  For debug purpose.
+  void SingletonExists(unsigned Opc);
+
+  bool PositionFiltered(unsigned i) {
+    return ValueSet(FilterBitValues[i]);
+  }
+
+  // Calculates the island(s) needed to decode the instruction.
+  // This returns a lit of undecoded bits of an instructions, for example,
+  // Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be
+  // decoded bits in order to verify that the instruction matches the Opcode.
+  unsigned getIslands(std::vector<unsigned> &StartBits,
+      std::vector<unsigned> &EndBits, std::vector<uint64_t> &FieldVals,
+      insn_t &Insn);
+
+  // The purpose of this function is for the API client to detect possible
+  // Load/Store Coprocessor instructions.  If the coprocessor number is of
+  // the instruction is either 10 or 11, the decoder should not report the
+  // instruction as LDC/LDC2/STC/STC2, but should match against Advanced SIMD or
+  // VFP instructions.
+  bool LdStCopEncoding1(unsigned Opc) {
+    const std::string &Name = nameWithID(Opc);
+    if (Name == "LDC_OFFSET" || Name == "LDC_OPTION" ||
+        Name == "LDC_POST" || Name == "LDC_PRE" ||
+        Name == "LDCL_OFFSET" || Name == "LDCL_OPTION" ||
+        Name == "LDCL_POST" || Name == "LDCL_PRE" ||
+        Name == "STC_OFFSET" || Name == "STC_OPTION" ||
+        Name == "STC_POST" || Name == "STC_PRE" ||
+        Name == "STCL_OFFSET" || Name == "STCL_OPTION" ||
+        Name == "STCL_POST" || Name == "STCL_PRE")
+      return true;
+    else
+      return false;
+  }
+
+  // Emits code to decode the singleton.  Return true if we have matched all the
+  // well-known bits.
+  bool emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,unsigned Opc);
+
+  // Emits code to decode the singleton, and then to decode the rest.
+  void emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,Filter &Best);
+
+  // Assign a single filter and run with it.
+  void runSingleFilter(FilterChooser &owner, unsigned startBit, unsigned numBit,
+      bool mixed);
+
+  // reportRegion is a helper function for filterProcessor to mark a region as
+  // eligible for use as a filter region.
+  void reportRegion(bitAttr_t RA, unsigned StartBit, unsigned BitIndex,
+      bool AllowMixed);
+
+  // FilterProcessor scans the well-known encoding bits of the instructions and
+  // builds up a list of candidate filters.  It chooses the best filter and
+  // recursively descends down the decoding tree.
+  bool filterProcessor(bool AllowMixed, bool Greedy = true);
+
+  // Decides on the best configuration of filter(s) to use in order to decode
+  // the instructions.  A conflict of instructions may occur, in which case we
+  // dump the conflict set to the standard error.
+  void doFilter();
+
+  // Emits code to decode our share of instructions.  Returns true if the
+  // emitted code causes a return, which occurs if we know how to decode
+  // the instruction at this level or the instruction is not decodeable.
+  bool emit(raw_ostream &o, unsigned &Indentation);
+};
+
+///////////////////////////
+//                       //
+// Filter Implmenetation //
+//                       //
+///////////////////////////
+
+Filter::Filter(const Filter &f) :
+  Owner(f.Owner), StartBit(f.StartBit), NumBits(f.NumBits), Mixed(f.Mixed),
+  FilteredInstructions(f.FilteredInstructions),
+  VariableInstructions(f.VariableInstructions),
+  FilterChooserMap(f.FilterChooserMap), NumFiltered(f.NumFiltered),
+  LastOpcFiltered(f.LastOpcFiltered), NumVariable(f.NumVariable) {
+}
+
+Filter::Filter(FilterChooser &owner, unsigned startBit, unsigned numBits,
+    bool mixed) : Owner(&owner), StartBit(startBit), NumBits(numBits),
+                  Mixed(mixed) {
+  assert(StartBit + NumBits - 1 < BIT_WIDTH);
+
+  NumFiltered = 0;
+  LastOpcFiltered = 0;
+  NumVariable = 0;
+
+  for (unsigned i = 0, e = Owner->Opcodes.size(); i != e; ++i) {
+    insn_t Insn;
+
+    // Populates the insn given the uid.
+    Owner->insnWithID(Insn, Owner->Opcodes[i]);
+
+    uint64_t Field;
+    // Scans the segment for possibly well-specified encoding bits.
+    bool ok = Owner->fieldFromInsn(Field, Insn, StartBit, NumBits);
+
+    if (ok) {
+      // The encoding bits are well-known.  Lets add the uid of the
+      // instruction into the bucket keyed off the constant field value.
+      LastOpcFiltered = Owner->Opcodes[i];
+      FilteredInstructions[Field].push_back(LastOpcFiltered);
+      ++NumFiltered;
+    } else {
+      // Some of the encoding bit(s) are unspecfied.  This contributes to
+      // one additional member of "Variable" instructions.
+      VariableInstructions.push_back(Owner->Opcodes[i]);
+      ++NumVariable;
+    }
+  }
+
+  assert((FilteredInstructions.size() + VariableInstructions.size() > 0)
+         && "Filter returns no instruction categories");
+}
+
+Filter::~Filter() {
+  std::map<unsigned, FilterChooser*>::iterator filterIterator;
+  for (filterIterator = FilterChooserMap.begin();
+       filterIterator != FilterChooserMap.end();
+       filterIterator++) {
+    delete filterIterator->second;
+  }
+}
+
+// Divides the decoding task into sub tasks and delegates them to the
+// inferior FilterChooser's.
+//
+// A special case arises when there's only one entry in the filtered
+// instructions.  In order to unambiguously decode the singleton, we need to
+// match the remaining undecoded encoding bits against the singleton.
+void Filter::recurse() {
+  std::map<uint64_t, std::vector<unsigned> >::const_iterator mapIterator;
+
+  bit_value_t BitValueArray[BIT_WIDTH];
+  // Starts by inheriting our parent filter chooser's filter bit values.
+  memcpy(BitValueArray, Owner->FilterBitValues, sizeof(BitValueArray));
+
+  unsigned bitIndex;
+
+  if (VariableInstructions.size()) {
+    // Conservatively marks each segment position as BIT_UNSET.
+    for (bitIndex = 0; bitIndex < NumBits; bitIndex++)
+      BitValueArray[StartBit + bitIndex] = BIT_UNSET;
+
+    // Delegates to an inferior filter chooser for futher processing on this
+    // group of instructions whose segment values are variable.
+    FilterChooserMap.insert(std::pair<unsigned, FilterChooser*>(
+                              (unsigned)-1,
+                              new FilterChooser(Owner->AllInstructions,
+                                                VariableInstructions,
+                                                BitValueArray,
+                                                *Owner)
+                              ));
+  }
+
+  // No need to recurse for a singleton filtered instruction.
+  // See also Filter::emit().
+  if (getNumFiltered() == 1) {
+    //Owner->SingletonExists(LastOpcFiltered);
+    assert(FilterChooserMap.size() == 1);
+    return;
+  }
+
+  // Otherwise, create sub choosers.
+  for (mapIterator = FilteredInstructions.begin();
+       mapIterator != FilteredInstructions.end();
+       mapIterator++) {
+
+    // Marks all the segment positions with either BIT_TRUE or BIT_FALSE.
+    for (bitIndex = 0; bitIndex < NumBits; bitIndex++) {
+      if (mapIterator->first & (1ULL << bitIndex))
+        BitValueArray[StartBit + bitIndex] = BIT_TRUE;
+      else
+        BitValueArray[StartBit + bitIndex] = BIT_FALSE;
+    }
+
+    // Delegates to an inferior filter chooser for futher processing on this
+    // category of instructions.
+    FilterChooserMap.insert(std::pair<unsigned, FilterChooser*>(
+                              mapIterator->first,
+                              new FilterChooser(Owner->AllInstructions,
+                                                mapIterator->second,
+                                                BitValueArray,
+                                                *Owner)
+                              ));
+  }
+}
+
+// Emit code to decode instructions given a segment or segments of bits.
+void Filter::emit(raw_ostream &o, unsigned &Indentation) {
+  o.indent(Indentation) << "// Check Inst{";
+
+  if (NumBits > 1)
+    o << (StartBit + NumBits - 1) << '-';
+
+  o << StartBit << "} ...\n";
+
+  o.indent(Indentation) << "switch (fieldFromInstruction(insn, "
+                        << StartBit << ", " << NumBits << ")) {\n";
+
+  std::map<unsigned, FilterChooser*>::iterator filterIterator;
+
+  bool DefaultCase = false;
+  for (filterIterator = FilterChooserMap.begin();
+       filterIterator != FilterChooserMap.end();
+       filterIterator++) {
+
+    // Field value -1 implies a non-empty set of variable instructions.
+    // See also recurse().
+    if (filterIterator->first == (unsigned)-1) {
+      DefaultCase = true;
+
+      o.indent(Indentation) << "default:\n";
+      o.indent(Indentation) << "  break; // fallthrough\n";
+
+      // Closing curly brace for the switch statement.
+      // This is unconventional because we want the default processing to be
+      // performed for the fallthrough cases as well, i.e., when the "cases"
+      // did not prove a decoded instruction.
+      o.indent(Indentation) << "}\n";
+
+    } else
+      o.indent(Indentation) << "case " << filterIterator->first << ":\n";
+
+    // We arrive at a category of instructions with the same segment value.
+    // Now delegate to the sub filter chooser for further decodings.
+    // The case may fallthrough, which happens if the remaining well-known
+    // encoding bits do not match exactly.
+    if (!DefaultCase) { ++Indentation; ++Indentation; }
+
+    bool finished = filterIterator->second->emit(o, Indentation);
+    // For top level default case, there's no need for a break statement.
+    if (Owner->isTopLevel() && DefaultCase)
+      break;
+    if (!finished)
+      o.indent(Indentation) << "break;\n";
+
+    if (!DefaultCase) { --Indentation; --Indentation; }
+  }
+
+  // If there is no default case, we still need to supply a closing brace.
+  if (!DefaultCase) {
+    // Closing curly brace for the switch statement.
+    o.indent(Indentation) << "}\n";
+  }
+}
+
+// Returns the number of fanout produced by the filter.  More fanout implies
+// the filter distinguishes more categories of instructions.
+unsigned Filter::usefulness() const {
+  if (VariableInstructions.size())
+    return FilteredInstructions.size();
+  else
+    return FilteredInstructions.size() + 1;
+}
+
+//////////////////////////////////
+//                              //
+// Filterchooser Implementation //
+//                              //
+//////////////////////////////////
+
+// Define the symbol here.
+TARGET_NAME_t FilterChooser::TargetName;
+
+// This provides an opportunity for target specific code emission.
+void FilterChooser::emitTopHook(raw_ostream &o) {
+  if (TargetName == TARGET_ARM) {
+    // Emit code that references the ARMFormat data type.
+    o << "static const ARMFormat ARMFormats[] = {\n";
+    for (unsigned i = 0, e = AllInstructions.size(); i != e; ++i) {
+      const Record &Def = *(AllInstructions[i]->TheDef);
+      const std::string &Name = Def.getName();
+      if (Def.isSubClassOf("InstARM") || Def.isSubClassOf("InstThumb"))
+        o.indent(2) << 
+          stringForARMFormat((ARMFormat)getByteField(Def, "Form"));
+      else
+        o << "  ARM_FORMAT_NA";
+
+      o << ",\t// Inst #" << i << " = " << Name << '\n';
+    }
+    o << "  ARM_FORMAT_NA\t// Unreachable.\n";
+    o << "};\n\n";
+  }
+}
+
+// Emit the top level typedef and decodeInstruction() function.
+void FilterChooser::emitTop(raw_ostream &o, unsigned &Indentation) {
+  // Run the target specific emit hook.
+  emitTopHook(o);
+
+  switch (BIT_WIDTH) {
+  case 8:
+    o.indent(Indentation) << "typedef uint8_t field_t;\n";
+    break;
+  case 16:
+    o.indent(Indentation) << "typedef uint16_t field_t;\n";
+    break;
+  case 32:
+    o.indent(Indentation) << "typedef uint32_t field_t;\n";
+    break;
+  case 64:
+    o.indent(Indentation) << "typedef uint64_t field_t;\n";
+    break;
+  default:
+    assert(0 && "Unexpected instruction size!");
+  }
+
+  o << '\n';
+
+  o.indent(Indentation) << "static field_t " <<
+    "fieldFromInstruction(field_t insn, unsigned startBit, unsigned numBits)\n";
+
+  o.indent(Indentation) << "{\n";
+
+  ++Indentation; ++Indentation;
+  o.indent(Indentation) << "assert(startBit + numBits <= " << BIT_WIDTH
+                        << " && \"Instruction field out of bounds!\");\n";
+  o << '\n';
+  o.indent(Indentation) << "field_t fieldMask;\n";
+  o << '\n';
+  o.indent(Indentation) << "if (numBits == " << BIT_WIDTH << ")\n";
+
+  ++Indentation; ++Indentation;
+  o.indent(Indentation) << "fieldMask = (field_t)-1;\n";
+  --Indentation; --Indentation;
+
+  o.indent(Indentation) << "else\n";
+
+  ++Indentation; ++Indentation;
+  o.indent(Indentation) << "fieldMask = ((1 << numBits) - 1) << startBit;\n";
+  --Indentation; --Indentation;
+
+  o << '\n';
+  o.indent(Indentation) << "return (insn & fieldMask) >> startBit;\n";
+  --Indentation; --Indentation;
+
+  o.indent(Indentation) << "}\n";
+
+  o << '\n';
+
+  o.indent(Indentation) << "static uint16_t decodeInstruction(field_t insn) {\n";
+
+  ++Indentation; ++Indentation;
+  // Emits code to decode the instructions.
+  emit(o, Indentation);
+
+  o << '\n';
+  o.indent(Indentation) << "return 0;\n";
+  --Indentation; --Indentation;
+
+  o.indent(Indentation) << "}\n";
+
+  o << '\n';
+}
+
+// This provides an opportunity for target specific code emission after
+// emitTop().
+void FilterChooser::emitBot(raw_ostream &o, unsigned &Indentation) {
+  if (TargetName != TARGET_THUMB) return;
+
+  // Emit code that decodes the Thumb ISA.
+  o.indent(Indentation)
+    << "static uint16_t decodeThumbInstruction(field_t insn) {\n";
+
+  ++Indentation; ++Indentation;
+
+  // Emits code to decode the instructions.
+  emit(o, Indentation);
+
+  o << '\n';
+  o.indent(Indentation) << "return 0;\n";
+
+  --Indentation; --Indentation;
+
+  o.indent(Indentation) << "}\n";
+}
+
+// Populates the field of the insn given the start position and the number of
+// consecutive bits to scan for.
+//
+// Returns false if and on the first uninitialized bit value encountered.
+// Returns true, otherwise.
+bool FilterChooser::fieldFromInsn(uint64_t &Field, insn_t &Insn,
+    unsigned StartBit, unsigned NumBits) const {
+  Field = 0;
+
+  for (unsigned i = 0; i < NumBits; ++i) {
+    if (Insn[StartBit + i] == BIT_UNSET)
+      return false;
+
+    if (Insn[StartBit + i] == BIT_TRUE)
+      Field = Field | (1ULL << i);
+  }
+
+  return true;
+}
+
+/// dumpFilterArray - dumpFilterArray prints out debugging info for the given
+/// filter array as a series of chars.
+void FilterChooser::dumpFilterArray(raw_ostream &o,
+    bit_value_t (&filter)[BIT_WIDTH]) {
+  unsigned bitIndex;
+
+  for (bitIndex = BIT_WIDTH; bitIndex > 0; bitIndex--) {
+    switch (filter[bitIndex - 1]) {
+    case BIT_UNFILTERED:
+      o << ".";
+      break;
+    case BIT_UNSET:
+      o << "_";
+      break;
+    case BIT_TRUE:
+      o << "1";
+      break;
+    case BIT_FALSE:
+      o << "0";
+      break;
+    }
+  }
+}
+
+/// dumpStack - dumpStack traverses the filter chooser chain and calls
+/// dumpFilterArray on each filter chooser up to the top level one.
+void FilterChooser::dumpStack(raw_ostream &o, const char *prefix) {
+  FilterChooser *current = this;
+
+  while (current) {
+    o << prefix;
+    dumpFilterArray(o, current->FilterBitValues);
+    o << '\n';
+    current = current->Parent;
+  }
+}
+
+// Called from Filter::recurse() when singleton exists.  For debug purpose.
+void FilterChooser::SingletonExists(unsigned Opc) {
+  insn_t Insn0;
+  insnWithID(Insn0, Opc);
+
+  errs() << "Singleton exists: " << nameWithID(Opc)
+         << " with its decoding dominating ";
+  for (unsigned i = 0; i < Opcodes.size(); ++i) {
+    if (Opcodes[i] == Opc) continue;
+    errs() << nameWithID(Opcodes[i]) << ' ';
+  }
+  errs() << '\n';
+
+  dumpStack(errs(), "\t\t");
+  for (unsigned i = 0; i < Opcodes.size(); i++) {
+    const std::string &Name = nameWithID(Opcodes[i]);
+
+    errs() << '\t' << Name << " ";
+    dumpBits(errs(),
+             getBitsField(*AllInstructions[Opcodes[i]]->TheDef, "Inst"));
+    errs() << '\n';
+  }
+}
+
+// Calculates the island(s) needed to decode the instruction.
+// This returns a list of undecoded bits of an instructions, for example,
+// Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be
+// decoded bits in order to verify that the instruction matches the Opcode.
+unsigned FilterChooser::getIslands(std::vector<unsigned> &StartBits,
+    std::vector<unsigned> &EndBits, std::vector<uint64_t> &FieldVals,
+    insn_t &Insn) {
+  unsigned Num, BitNo;
+  Num = BitNo = 0;
+
+  uint64_t FieldVal = 0;
+
+  // 0: Init
+  // 1: Water (the bit value does not affect decoding)
+  // 2: Island (well-known bit value needed for decoding)
+  int State = 0;
+  int Val = -1;
+
+  for (unsigned i = 0; i < BIT_WIDTH; ++i) {
+    Val = Value(Insn[i]);
+    bool Filtered = PositionFiltered(i);
+    switch (State) {
+    default:
+      assert(0 && "Unreachable code!");
+      break;
+    case 0:
+    case 1:
+      if (Filtered || Val == -1)
+        State = 1; // Still in Water
+      else {
+        State = 2; // Into the Island
+        BitNo = 0;
+        StartBits.push_back(i);
+        FieldVal = Val;
+      }
+      break;
+    case 2:
+      if (Filtered || Val == -1) {
+        State = 1; // Into the Water
+        EndBits.push_back(i - 1);
+        FieldVals.push_back(FieldVal);
+        ++Num;
+      } else {
+        State = 2; // Still in Island
+        ++BitNo;
+        FieldVal = FieldVal | Val << BitNo;
+      }
+      break;
+    }
+  }
+  // If we are still in Island after the loop, do some housekeeping.
+  if (State == 2) {
+    EndBits.push_back(BIT_WIDTH - 1);
+    FieldVals.push_back(FieldVal);
+    ++Num;
+  }
+
+  assert(StartBits.size() == Num && EndBits.size() == Num &&
+         FieldVals.size() == Num);
+  return Num;
+}
+
+// Emits code to decode the singleton.  Return true if we have matched all the
+// well-known bits.
+bool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,
+                                         unsigned Opc) {
+  std::vector<unsigned> StartBits;
+  std::vector<unsigned> EndBits;
+  std::vector<uint64_t> FieldVals;
+  insn_t Insn;
+  insnWithID(Insn, Opc);
+
+  // This provides a good opportunity to check for possible Ld/St Coprocessor
+  // Opcode and escapes if the coproc # is either 10 or 11.  It is a NEON/VFP
+  // instruction is disguise.
+  if (TargetName == TARGET_ARM && LdStCopEncoding1(Opc)) {
+    o.indent(Indentation);
+    // A8.6.51 & A8.6.188
+    // If coproc = 0b101?, i.e, slice(insn, 11, 8) = 10 or 11, escape.
+    o << "if (fieldFromInstruction(insn, 9, 3) == 5) break; // fallthrough\n";
+  }
+
+  // Look for islands of undecoded bits of the singleton.
+  getIslands(StartBits, EndBits, FieldVals, Insn);
+
+  unsigned Size = StartBits.size();
+  unsigned I, NumBits;
+
+  // If we have matched all the well-known bits, just issue a return.
+  if (Size == 0) {
+    o.indent(Indentation) << "return " << Opc << "; // " << nameWithID(Opc)
+                          << '\n';
+    return true;
+  }
+
+  // Otherwise, there are more decodings to be done!
+
+  // Emit code to match the island(s) for the singleton.
+  o.indent(Indentation) << "// Check ";
+
+  for (I = Size; I != 0; --I) {
+    o << "Inst{" << EndBits[I-1] << '-' << StartBits[I-1] << "} ";
+    if (I > 1)
+      o << "&& ";
+    else
+      o << "for singleton decoding...\n";
+  }
+
+  o.indent(Indentation) << "if (";
+
+  for (I = Size; I != 0; --I) {
+    NumBits = EndBits[I-1] - StartBits[I-1] + 1;
+    o << "fieldFromInstruction(insn, " << StartBits[I-1] << ", " << NumBits
+      << ") == " << FieldVals[I-1];
+    if (I > 1)
+      o << " && ";
+    else
+      o << ")\n";
+  }
+
+  o.indent(Indentation) << "  return " << Opc << "; // " << nameWithID(Opc)
+                        << '\n';
+
+  return false;
+}
+
+// Emits code to decode the singleton, and then to decode the rest.
+void FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,
+    Filter &Best) {
+
+  unsigned Opc = Best.getSingletonOpc();
+
+  emitSingletonDecoder(o, Indentation, Opc);
+
+  // Emit code for the rest.
+  o.indent(Indentation) << "else\n";
+
+  Indentation += 2;
+  Best.getVariableFC().emit(o, Indentation);
+  Indentation -= 2;
+}
+
+// Assign a single filter and run with it.  Top level API client can initialize
+// with a single filter to start the filtering process.
+void FilterChooser::runSingleFilter(FilterChooser &owner, unsigned startBit,
+    unsigned numBit, bool mixed) {
+  Filters.clear();
+  Filter F(*this, startBit, numBit, true);
+  Filters.push_back(F);
+  BestIndex = 0; // Sole Filter instance to choose from.
+  bestFilter().recurse();
+}
+
+// reportRegion is a helper function for filterProcessor to mark a region as
+// eligible for use as a filter region.
+void FilterChooser::reportRegion(bitAttr_t RA, unsigned StartBit,
+    unsigned BitIndex, bool AllowMixed) {
+  if (RA == ATTR_MIXED && AllowMixed)
+    Filters.push_back(Filter(*this, StartBit, BitIndex - StartBit, true));   
+  else if (RA == ATTR_ALL_SET && !AllowMixed)
+    Filters.push_back(Filter(*this, StartBit, BitIndex - StartBit, false));
+}
+
+// FilterProcessor scans the well-known encoding bits of the instructions and
+// builds up a list of candidate filters.  It chooses the best filter and
+// recursively descends down the decoding tree.
+bool FilterChooser::filterProcessor(bool AllowMixed, bool Greedy) {
+  Filters.clear();
+  BestIndex = -1;
+  unsigned numInstructions = Opcodes.size();
+
+  assert(numInstructions && "Filter created with no instructions");
+
+  // No further filtering is necessary.
+  if (numInstructions == 1)
+    return true;
+
+  // Heuristics.  See also doFilter()'s "Heuristics" comment when num of
+  // instructions is 3.
+  if (AllowMixed && !Greedy) {
+    assert(numInstructions == 3);
+
+    for (unsigned i = 0; i < Opcodes.size(); ++i) {
+      std::vector<unsigned> StartBits;
+      std::vector<unsigned> EndBits;
+      std::vector<uint64_t> FieldVals;
+      insn_t Insn;
+
+      insnWithID(Insn, Opcodes[i]);
+
+      // Look for islands of undecoded bits of any instruction.
+      if (getIslands(StartBits, EndBits, FieldVals, Insn) > 0) {
+        // Found an instruction with island(s).  Now just assign a filter.
+        runSingleFilter(*this, StartBits[0], EndBits[0] - StartBits[0] + 1,
+                        true);
+        return true;
+      }
+    }
+  }
+
+  unsigned BitIndex, InsnIndex;
+
+  // We maintain BIT_WIDTH copies of the bitAttrs automaton.
+  // The automaton consumes the corresponding bit from each
+  // instruction.
+  //
+  //   Input symbols: 0, 1, and _ (unset).
+  //   States:        NONE, FILTERED, ALL_SET, ALL_UNSET, and MIXED.
+  //   Initial state: NONE.
+  //
+  // (NONE) ------- [01] -> (ALL_SET)
+  // (NONE) ------- _ ----> (ALL_UNSET)
+  // (ALL_SET) ---- [01] -> (ALL_SET)
+  // (ALL_SET) ---- _ ----> (MIXED)
+  // (ALL_UNSET) -- [01] -> (MIXED)
+  // (ALL_UNSET) -- _ ----> (ALL_UNSET)
+  // (MIXED) ------ . ----> (MIXED)
+  // (FILTERED)---- . ----> (FILTERED)
+
+  bitAttr_t bitAttrs[BIT_WIDTH];
+
+  // FILTERED bit positions provide no entropy and are not worthy of pursuing.
+  // Filter::recurse() set either BIT_TRUE or BIT_FALSE for each position.
+  for (BitIndex = 0; BitIndex < BIT_WIDTH; ++BitIndex)
+    if (FilterBitValues[BitIndex] == BIT_TRUE ||
+        FilterBitValues[BitIndex] == BIT_FALSE)
+      bitAttrs[BitIndex] = ATTR_FILTERED;
+    else
+      bitAttrs[BitIndex] = ATTR_NONE;
+
+  for (InsnIndex = 0; InsnIndex < numInstructions; ++InsnIndex) {
+    insn_t insn;
+
+    insnWithID(insn, Opcodes[InsnIndex]);
+
+    for (BitIndex = 0; BitIndex < BIT_WIDTH; ++BitIndex) {
+      switch (bitAttrs[BitIndex]) {
+      case ATTR_NONE:
+        if (insn[BitIndex] == BIT_UNSET)
+          bitAttrs[BitIndex] = ATTR_ALL_UNSET;
+        else
+          bitAttrs[BitIndex] = ATTR_ALL_SET;
+        break;
+      case ATTR_ALL_SET:
+        if (insn[BitIndex] == BIT_UNSET)
+          bitAttrs[BitIndex] = ATTR_MIXED;
+        break;
+      case ATTR_ALL_UNSET:
+        if (insn[BitIndex] != BIT_UNSET)
+          bitAttrs[BitIndex] = ATTR_MIXED;
+        break;
+      case ATTR_MIXED:
+      case ATTR_FILTERED:
+        break;
+      }
+    }
+  }
+
+  // The regionAttr automaton consumes the bitAttrs automatons' state,
+  // lowest-to-highest.
+  //
+  //   Input symbols: F(iltered), (all_)S(et), (all_)U(nset), M(ixed)
+  //   States:        NONE, ALL_SET, MIXED
+  //   Initial state: NONE
+  //
+  // (NONE) ----- F --> (NONE)
+  // (NONE) ----- S --> (ALL_SET)     ; and set region start
+  // (NONE) ----- U --> (NONE)
+  // (NONE) ----- M --> (MIXED)       ; and set region start
+  // (ALL_SET) -- F --> (NONE)        ; and report an ALL_SET region
+  // (ALL_SET) -- S --> (ALL_SET)
+  // (ALL_SET) -- U --> (NONE)        ; and report an ALL_SET region
+  // (ALL_SET) -- M --> (MIXED)       ; and report an ALL_SET region
+  // (MIXED) ---- F --> (NONE)        ; and report a MIXED region
+  // (MIXED) ---- S --> (ALL_SET)     ; and report a MIXED region
+  // (MIXED) ---- U --> (NONE)        ; and report a MIXED region
+  // (MIXED) ---- M --> (MIXED)
+
+  bitAttr_t RA = ATTR_NONE;
+  unsigned StartBit = 0;
+
+  for (BitIndex = 0; BitIndex < BIT_WIDTH; BitIndex++) {
+    bitAttr_t bitAttr = bitAttrs[BitIndex];
+
+    assert(bitAttr != ATTR_NONE && "Bit without attributes");
+
+    switch (RA) {
+    case ATTR_NONE:
+      switch (bitAttr) {
+      case ATTR_FILTERED:
+        break;
+      case ATTR_ALL_SET:
+        StartBit = BitIndex;
+        RA = ATTR_ALL_SET;
+        break;
+      case ATTR_ALL_UNSET:
+        break;
+      case ATTR_MIXED:
+        StartBit = BitIndex;
+        RA = ATTR_MIXED;
+        break;
+      default:
+        assert(0 && "Unexpected bitAttr!");
+      }
+      break;
+    case ATTR_ALL_SET:
+      switch (bitAttr) {
+      case ATTR_FILTERED:
+        reportRegion(RA, StartBit, BitIndex, AllowMixed);
+        RA = ATTR_NONE;
+        break;
+      case ATTR_ALL_SET:
+        break;
+      case ATTR_ALL_UNSET:
+        reportRegion(RA, StartBit, BitIndex, AllowMixed);
+        RA = ATTR_NONE;
+        break;
+      case ATTR_MIXED:
+        reportRegion(RA, StartBit, BitIndex, AllowMixed);
+        StartBit = BitIndex;
+        RA = ATTR_MIXED;
+        break;
+      default:
+        assert(0 && "Unexpected bitAttr!");
+      }
+      break;
+    case ATTR_MIXED:
+      switch (bitAttr) {
+      case ATTR_FILTERED:
+        reportRegion(RA, StartBit, BitIndex, AllowMixed);
+        StartBit = BitIndex;
+        RA = ATTR_NONE;
+        break;
+      case ATTR_ALL_SET:
+        reportRegion(RA, StartBit, BitIndex, AllowMixed);
+        StartBit = BitIndex;
+        RA = ATTR_ALL_SET;
+        break;
+      case ATTR_ALL_UNSET:
+        reportRegion(RA, StartBit, BitIndex, AllowMixed);
+        RA = ATTR_NONE;
+        break;
+      case ATTR_MIXED:
+        break;
+      default:
+        assert(0 && "Unexpected bitAttr!");
+      }
+      break;
+    case ATTR_ALL_UNSET:
+      assert(0 && "regionAttr state machine has no ATTR_UNSET state");
+    case ATTR_FILTERED:
+      assert(0 && "regionAttr state machine has no ATTR_FILTERED state");
+    }
+  }
+
+  // At the end, if we're still in ALL_SET or MIXED states, report a region
+  switch (RA) {
+  case ATTR_NONE:
+    break;
+  case ATTR_FILTERED:
+    break;
+  case ATTR_ALL_SET:
+    reportRegion(RA, StartBit, BitIndex, AllowMixed);
+    break;
+  case ATTR_ALL_UNSET:
+    break;
+  case ATTR_MIXED:
+    reportRegion(RA, StartBit, BitIndex, AllowMixed);
+    break;
+  }
+
+  // We have finished with the filter processings.  Now it's time to choose
+  // the best performing filter.
+  BestIndex = 0;
+  bool AllUseless = true;
+  unsigned BestScore = 0;
+
+  for (unsigned i = 0, e = Filters.size(); i != e; ++i) {
+    unsigned Usefulness = Filters[i].usefulness();
+
+    if (Usefulness)
+      AllUseless = false;
+
+    if (Usefulness > BestScore) {
+      BestIndex = i;
+      BestScore = Usefulness;
+    }
+  }
+
+  if (!AllUseless)
+    bestFilter().recurse();
+
+  return !AllUseless;
+} // end of FilterChooser::filterProcessor(bool)
+
+// Decides on the best configuration of filter(s) to use in order to decode
+// the instructions.  A conflict of instructions may occur, in which case we
+// dump the conflict set to the standard error.
+void FilterChooser::doFilter() {
+  unsigned Num = Opcodes.size();
+  assert(Num && "FilterChooser created with no instructions");
+
+  // Heuristics: Use Inst{31-28} as the top level filter for ARM ISA.
+  if (TargetName == TARGET_ARM && Parent == NULL) {
+    runSingleFilter(*this, 28, 4, false);
+    return;
+  }
+
+  // Try regions of consecutive known bit values first. 
+  if (filterProcessor(false))
+    return;
+
+  // Then regions of mixed bits (both known and unitialized bit values allowed).
+  if (filterProcessor(true))
+    return;
+
+  // Heuristics to cope with conflict set {t2CMPrs, t2SUBSrr, t2SUBSrs} where
+  // no single instruction for the maximum ATTR_MIXED region Inst{14-4} has a
+  // well-known encoding pattern.  In such case, we backtrack and scan for the
+  // the very first consecutive ATTR_ALL_SET region and assign a filter to it.
+  if (Num == 3 && filterProcessor(true, false))
+    return;
+
+  // If we come to here, the instruction decoding has failed.
+  // Set the BestIndex to -1 to indicate so.
+  BestIndex = -1;
+}
+
+// Emits code to decode our share of instructions.  Returns true if the
+// emitted code causes a return, which occurs if we know how to decode
+// the instruction at this level or the instruction is not decodeable.
+bool FilterChooser::emit(raw_ostream &o, unsigned &Indentation) {
+  if (Opcodes.size() == 1)
+    // There is only one instruction in the set, which is great!
+    // Call emitSingletonDecoder() to see whether there are any remaining
+    // encodings bits.
+    return emitSingletonDecoder(o, Indentation, Opcodes[0]);
+
+  // Choose the best filter to do the decodings!
+  if (BestIndex != -1) {
+    Filter &Best = bestFilter();
+    if (Best.getNumFiltered() == 1)
+      emitSingletonDecoder(o, Indentation, Best);
+    else
+      bestFilter().emit(o, Indentation);
+    return false;
+  }
+
+  // If we reach here, there is a conflict in decoding.  Let's resolve the known
+  // conflicts!
+  if ((TargetName == TARGET_ARM || TargetName == TARGET_THUMB) &&
+      Opcodes.size() == 2) {
+    // Resolve the known conflict sets:
+    //
+    // 1. source registers are identical => VMOVDneon; otherwise => VORRd
+    // 2. source registers are identical => VMOVQ; otherwise => VORRq
+    // 3. LDR, LDRcp => return LDR for now.
+    // FIXME: How can we distinguish between LDR and LDRcp?  Do we need to?
+    // 4. tLDM, tLDM_UPD => Rn = Inst{10-8}, reglist = Inst{7-0},
+    //    wback = registers<Rn> = 0
+    // NOTE: (tLDM, tLDM_UPD) resolution must come before Advanced SIMD
+    //       addressing mode resolution!!!
+    // 5. VLD[234]LN*/VST[234]LN* vs. VLD[234]LN*_UPD/VST[234]LN*_UPD conflicts
+    //    are resolved returning the non-UPD versions of the instructions if the
+    //    Rm field, i.e., Inst{3-0} is 0b1111.  This is specified in A7.7.1
+    //    Advanced SIMD addressing mode.
+    const std::string &name1 = nameWithID(Opcodes[0]);
+    const std::string &name2 = nameWithID(Opcodes[1]);
+    if ((name1 == "VMOVDneon" && name2 == "VORRd") ||
+        (name1 == "VMOVQ" && name2 == "VORRq")) {
+      // Inserting the opening curly brace for this case block.
+      --Indentation; --Indentation;
+      o.indent(Indentation) << "{\n";
+      ++Indentation; ++Indentation;
+
+      o.indent(Indentation)
+        << "field_t N = fieldFromInstruction(insn, 7, 1), "
+        << "M = fieldFromInstruction(insn, 5, 1);\n";
+      o.indent(Indentation)
+        << "field_t Vn = fieldFromInstruction(insn, 16, 4), "
+        << "Vm = fieldFromInstruction(insn, 0, 4);\n";
+      o.indent(Indentation)
+        << "return (N == M && Vn == Vm) ? "
+        << Opcodes[0] << " /* " << name1 << " */ : "
+        << Opcodes[1] << " /* " << name2 << " */ ;\n";
+
+      // Inserting the closing curly brace for this case block.
+      --Indentation; --Indentation;
+      o.indent(Indentation) << "}\n";
+      ++Indentation; ++Indentation;
+
+      return true;
+    }
+    if (name1 == "LDR" && name2 == "LDRcp") {
+      o.indent(Indentation)
+        << "return " << Opcodes[0]
+        << "; // Returning LDR for {LDR, LDRcp}\n";
+      return true;
+    }
+    if (name1 == "tLDM" && name2 == "tLDM_UPD") {
+      // Inserting the opening curly brace for this case block.
+      --Indentation; --Indentation;
+      o.indent(Indentation) << "{\n";
+      ++Indentation; ++Indentation;
+      
+      o.indent(Indentation)
+        << "unsigned Rn = fieldFromInstruction(insn, 8, 3), "
+        << "list = fieldFromInstruction(insn, 0, 8);\n";
+      o.indent(Indentation)
+        << "return ((list >> Rn) & 1) == 0 ? "
+        << Opcodes[1] << " /* " << name2 << " */ : "
+        << Opcodes[0] << " /* " << name1 << " */ ;\n";
+
+      // Inserting the closing curly brace for this case block.
+      --Indentation; --Indentation;
+      o.indent(Indentation) << "}\n";
+      ++Indentation; ++Indentation;
+
+      return true;
+    }
+    if (sameStringExceptSuffix(name1, name2, "_UPD")) {
+      o.indent(Indentation)
+        << "return fieldFromInstruction(insn, 0, 4) == 15 ? " << Opcodes[0]
+        << " /* " << name1 << " */ : " << Opcodes[1] << "/* " << name2
+        << " */ ; // Advanced SIMD addressing mode\n";
+      return true;
+    }
+
+    // Otherwise, it does not belong to the known conflict sets.
+  }
+
+  // We don't know how to decode these instructions!  Return 0 and dump the
+  // conflict set!
+  o.indent(Indentation) << "return 0;" << " // Conflict set: ";
+  for (int i = 0, N = Opcodes.size(); i < N; ++i) {
+    o << nameWithID(Opcodes[i]);
+    if (i < (N - 1))
+      o << ", ";
+    else
+      o << '\n';
+  }
+
+  // Print out useful conflict information for postmortem analysis.
+  errs() << "Decoding Conflict:\n";
+
+  dumpStack(errs(), "\t\t");
+
+  for (unsigned i = 0; i < Opcodes.size(); i++) {
+    const std::string &Name = nameWithID(Opcodes[i]);
+
+    errs() << '\t' << Name << " ";
+    dumpBits(errs(),
+             getBitsField(*AllInstructions[Opcodes[i]]->TheDef, "Inst"));
+    errs() << '\n';
+  }
+
+  return true;
+}
+
+
+////////////////////////////////////////////
+//                                        //
+//  ARMDEBackend                          //
+//  (Helper class for ARMDecoderEmitter)  //
+//                                        //
+////////////////////////////////////////////
+
+class ARMDecoderEmitter::ARMDEBackend {
+public:
+  ARMDEBackend(ARMDecoderEmitter &frontend) :
+    NumberedInstructions(),
+    Opcodes(),
+    Frontend(frontend),
+    Target(),
+    FC(NULL)
+  {
+    if (Target.getName() == "ARM")
+      TargetName = TARGET_ARM;
+    else {
+      errs() << "Target name " << Target.getName() << " not recognized\n";
+      assert(0 && "Unknown target");
+    }
+
+    // Populate the instructions for our TargetName.
+    populateInstructions();
+  }
+
+  ~ARMDEBackend() {
+    if (FC) {
+      delete FC;
+      FC = NULL;
+    }
+  }
+
+  void getInstructionsByEnumValue(std::vector<const CodeGenInstruction*>
+                                                &NumberedInstructions) {
+    // We must emit the PHI opcode first...
+    std::string Namespace = Target.getInstNamespace();
+    assert(!Namespace.empty() && "No instructions defined.");
+
+    NumberedInstructions = Target.getInstructionsByEnumValue();
+  }
+
+  bool populateInstruction(const CodeGenInstruction &CGI, TARGET_NAME_t TN);
+
+  void populateInstructions();
+
+  // Emits disassembler code for instruction decoding.  This delegates to the
+  // FilterChooser instance to do the heavy lifting.
+  void emit(raw_ostream &o);
+
+protected:
+  std::vector<const CodeGenInstruction*> NumberedInstructions;
+  std::vector<unsigned> Opcodes;
+  // Special case for the ARM chip, which supports ARM and Thumb ISAs.
+  // Opcodes2 will be populated with the Thumb opcodes.
+  std::vector<unsigned> Opcodes2;
+  ARMDecoderEmitter &Frontend;
+  CodeGenTarget Target;
+  FilterChooser *FC;
+
+  TARGET_NAME_t TargetName;
+};
+
+bool ARMDecoderEmitter::ARMDEBackend::populateInstruction(
+    const CodeGenInstruction &CGI, TARGET_NAME_t TN) {
+  const Record &Def = *CGI.TheDef;
+  const StringRef Name = Def.getName();
+  uint8_t Form = getByteField(Def, "Form");
+
+  BitsInit &Bits = getBitsField(Def, "Inst");
+
+  // If all the bit positions are not specified; do not decode this instruction.
+  // We are bound to fail!  For proper disassembly, the well-known encoding bits
+  // of the instruction must be fully specified.
+  //
+  // This also removes pseudo instructions from considerations of disassembly,
+  // which is a better design and less fragile than the name matchings.
+  if (Bits.allInComplete()) return false;
+
+  if (TN == TARGET_ARM) {
+    // FIXME: what about Int_MemBarrierV6 and Int_SyncBarrierV6?
+    if ((Name != "Int_MemBarrierV7" && Name != "Int_SyncBarrierV7") &&
+        Form == ARM_FORMAT_PSEUDO)
+      return false;
+    if (thumbInstruction(Form))
+      return false;
+    if (Name.find("CMPz") != std::string::npos /* ||
+        Name.find("CMNz") != std::string::npos */)
+      return false;
+
+    // Ignore pseudo instructions.
+    if (Name == "BXr9" || Name == "BMOVPCRX" || Name == "BMOVPCRXr9")
+      return false;
+
+    // Tail calls are other patterns that generate existing instructions.
+    if (Name == "TCRETURNdi" || Name == "TCRETURNdiND" ||
+        Name == "TCRETURNri" || Name == "TCRETURNriND" ||
+        Name == "TAILJMPd"  || Name == "TAILJMPdt" ||
+        Name == "TAILJMPdND" || Name == "TAILJMPdNDt" ||
+        Name == "TAILJMPr"  || Name == "TAILJMPrND" ||
+        Name == "MOVr_TC")
+      return false;
+
+    // VLDMQ/VSTMQ can be hanlded with the more generic VLDMD/VSTMD.
+    if (Name == "VLDMQ" || Name == "VLDMQ_UPD" ||
+        Name == "VSTMQ" || Name == "VSTMQ_UPD")
+      return false;
+
+    //
+    // The following special cases are for conflict resolutions.
+    //
+
+    // NEON NLdStFrm conflict resolutions:
+    //
+    // 1. Ignore suffix "odd" and "odd_UPD", prefer the "even" register-
+    //    numbered ones which have the same Asm format string.
+    // 2. Ignore VST2d64_UPD, which conflicts with VST1q64_UPD.
+    // 3. Ignore VLD2d64_UPD, which conflicts with VLD1q64_UPD.
+    // 4. Ignore VLD1q[_UPD], which conflicts with VLD1q64[_UPD].
+    // 5. Ignore VST1q[_UPD], which conflicts with VST1q64[_UPD].
+    if (Name.endswith("odd") || Name.endswith("odd_UPD") ||
+        Name == "VST2d64_UPD" || Name == "VLD2d64_UPD" ||
+        Name == "VLD1q" || Name == "VLD1q_UPD" ||
+        Name == "VST1q" || Name == "VST1q_UPD")
+      return false;
+
+    // RSCSri and RSCSrs set the 's' bit, but are not predicated.  We are
+    // better off using the generic RSCri and RSCrs instructions.
+    if (Name == "RSCSri" || Name == "RSCSrs") return false;
+
+    // MOVCCr, MOVCCs, MOVCCi, FCYPScc, FCYPDcc, FNEGScc, and FNEGDcc are used
+    // in the compiler to implement conditional moves.  We can ignore them in
+    // favor of their more generic versions of instructions.
+    // See also SDNode *ARMDAGToDAGISel::Select(SDValue Op).
+    if (Name == "MOVCCr" || Name == "MOVCCs" || Name == "MOVCCi" ||
+        Name == "FCPYScc" || Name == "FCPYDcc" ||
+        Name == "FNEGScc" || Name == "FNEGDcc")
+      return false;
+
+    // Ditto for VMOVDcc, VMOVScc, VNEGDcc, and VNEGScc.
+    if (Name == "VMOVDcc" || Name == "VMOVScc" || Name == "VNEGDcc" ||
+        Name == "VNEGScc")
+      return false;
+
+    // Ignore the *_sfp instructions when decoding.  They are used by the
+    // compiler to implement scalar floating point operations using vector
+    // operations in order to work around some performance issues.
+    if (Name.find("_sfp") != std::string::npos) return false;
+
+    // LDM_RET is a special case of LDM (Load Multiple) where the registers
+    // loaded include the PC, causing a branch to a loaded address.  Ignore
+    // the LDM_RET instruction when decoding.
+    if (Name == "LDM_RET") return false;
+
+    // Bcc is in a more generic form than B.  Ignore B when decoding.
+    if (Name == "B") return false;
+
+    // Ignore the non-Darwin BL instructions and the TPsoft (TLS) instruction.
+    if (Name == "BL" || Name == "BL_pred" || Name == "BLX" || Name == "BX" ||
+        Name == "TPsoft")
+      return false;
+
+    // Ignore VDUPf[d|q] instructions known to conflict with VDUP32[d-q] for
+    // decoding.  The instruction duplicates an element from an ARM core
+    // register into every element of the destination vector.  There is no
+    // distinction between data types.
+    if (Name == "VDUPfd" || Name == "VDUPfq") return false;
+
+    // A8-598: VEXT
+    // Vector Extract extracts elements from the bottom end of the second
+    // operand vector and the top end of the first, concatenates them and
+    // places the result in the destination vector.  The elements of the
+    // vectors are treated as being 8-bit bitfields.  There is no distinction
+    // between data types.  The size of the operation can be specified in
+    // assembler as vext.size.  If the value is 16, 32, or 64, the syntax is
+    // a pseudo-instruction for a VEXT instruction specifying the equivalent
+    // number of bytes.
+    //
+    // Variants VEXTd16, VEXTd32, VEXTd8, and VEXTdf are reduced to VEXTd8;
+    // variants VEXTq16, VEXTq32, VEXTq8, and VEXTqf are reduced to VEXTq8.
+    if (Name == "VEXTd16" || Name == "VEXTd32" || Name == "VEXTdf" ||
+        Name == "VEXTq16" || Name == "VEXTq32" || Name == "VEXTqf")
+      return false;
+
+    // Vector Reverse is similar to Vector Extract.  There is no distinction
+    // between data types, other than size.
+    //
+    // VREV64df is equivalent to VREV64d32.
+    // VREV64qf is equivalent to VREV64q32.
+    if (Name == "VREV64df" || Name == "VREV64qf") return false;
+
+    // VDUPLNfd is equivalent to VDUPLN32d; VDUPfdf is specialized VDUPLN32d.
+    // VDUPLNfq is equivalent to VDUPLN32q; VDUPfqf is specialized VDUPLN32q.
+    // VLD1df is equivalent to VLD1d32.
+    // VLD1qf is equivalent to VLD1q32.
+    // VLD2d64 is equivalent to VLD1q64.
+    // VST1df is equivalent to VST1d32.
+    // VST1qf is equivalent to VST1q32.
+    // VST2d64 is equivalent to VST1q64.
+    if (Name == "VDUPLNfd" || Name == "VDUPfdf" ||
+        Name == "VDUPLNfq" || Name == "VDUPfqf" ||
+        Name == "VLD1df" || Name == "VLD1qf" || Name == "VLD2d64" ||
+        Name == "VST1df" || Name == "VST1qf" || Name == "VST2d64")
+      return false;
+  } else if (TN == TARGET_THUMB) {
+    if (!thumbInstruction(Form))
+      return false;
+
+    // On Darwin R9 is call-clobbered.  Ignore the non-Darwin counterparts.
+    if (Name == "tBL" || Name == "tBLXi" || Name == "tBLXr")
+      return false;
+
+    // Ignore the TPsoft (TLS) instructions, which conflict with tBLr9.
+    if (Name == "tTPsoft" || Name == "t2TPsoft")
+      return false;
+
+    // Ignore tLEApcrel and tLEApcrelJT, prefer tADDrPCi.
+    if (Name == "tLEApcrel" || Name == "tLEApcrelJT")
+      return false;
+
+    // Ignore t2LEApcrel, prefer the generic t2ADD* for disassembly printing.
+    if (Name == "t2LEApcrel")
+      return false;
+
+    // Ignore tADDrSP, tADDspr, and tPICADD, prefer the generic tADDhirr.
+    // Ignore t2SUBrSPs, prefer the t2SUB[S]r[r|s].
+    // Ignore t2ADDrSPs, prefer the t2ADD[S]r[r|s].
+    // Ignore t2ADDrSPi/t2SUBrSPi, which have more generic couterparts.
+    // Ignore t2ADDrSPi12/t2SUBrSPi12, which have more generic couterparts
+    if (Name == "tADDrSP" || Name == "tADDspr" || Name == "tPICADD" ||
+        Name == "t2SUBrSPs" || Name == "t2ADDrSPs" ||
+        Name == "t2ADDrSPi" || Name == "t2SUBrSPi" ||
+        Name == "t2ADDrSPi12" || Name == "t2SUBrSPi12")
+      return false;
+
+    // Ignore t2LDRDpci, prefer the generic t2LDRDi8, t2LDRD_PRE, t2LDRD_POST.
+    if (Name == "t2LDRDpci")
+      return false;
+
+    // Ignore t2TBB, t2TBH and prefer the generic t2TBBgen, t2TBHgen.
+    if (Name == "t2TBB" || Name == "t2TBH")
+      return false;
+
+    // Resolve conflicts:
+    //
+    //   tBfar conflicts with tBLr9
+    //   tCMNz conflicts with tCMN (with assembly format strings being equal)
+    //   tPOP_RET/t2LDM_RET conflict with tPOP/t2LDM (ditto)
+    //   tMOVCCi conflicts with tMOVi8
+    //   tMOVCCr conflicts with tMOVgpr2gpr
+    //   tBR_JTr conflicts with tBRIND
+    //   tSpill conflicts with tSTRspi
+    //   tLDRcp conflicts with tLDRspi
+    //   tRestore conflicts with tLDRspi
+    //   t2LEApcrelJT conflicts with t2LEApcrel
+    if (Name == "tBfar" ||
+        /* Name == "tCMNz" || */ Name == "tCMPzi8" || Name == "tCMPzr" ||
+        Name == "tCMPzhir" || /* Name == "t2CMNzrr" || Name == "t2CMNzrs" ||
+        Name == "t2CMNzri" || */ Name == "t2CMPzrr" || Name == "t2CMPzrs" ||
+        Name == "t2CMPzri" || Name == "tPOP_RET" || Name == "t2LDM_RET" ||
+        Name == "tMOVCCi" || Name == "tMOVCCr" || Name == "tBR_JTr" ||
+        Name == "tSpill" || Name == "tLDRcp" || Name == "tRestore" ||
+        Name == "t2LEApcrelJT")
+      return false;
+  }
+
+  // Dumps the instruction encoding format.
+  switch (TargetName) {
+  case TARGET_ARM:
+  case TARGET_THUMB:
+    DEBUG(errs() << Name << " " << stringForARMFormat((ARMFormat)Form));
+    break;
+  }
+
+  DEBUG({
+      errs() << " ";
+
+      // Dumps the instruction encoding bits.
+      dumpBits(errs(), Bits);
+
+      errs() << '\n';
+
+      // Dumps the list of operand info.
+      for (unsigned i = 0, e = CGI.OperandList.size(); i != e; ++i) {
+        CodeGenInstruction::OperandInfo Info = CGI.OperandList[i];
+        const std::string &OperandName = Info.Name;
+        const Record &OperandDef = *Info.Rec;
+
+        errs() << "\t" << OperandName << " (" << OperandDef.getName() << ")\n";
+      }
+    });
+
+  return true;
+}
+
+void ARMDecoderEmitter::ARMDEBackend::populateInstructions() {
+  getInstructionsByEnumValue(NumberedInstructions);
+
+  uint16_t numUIDs = NumberedInstructions.size();
+  uint16_t uid;
+
+  const char *instClass = NULL;
+
+  switch (TargetName) {
+  case TARGET_ARM:
+    instClass = "InstARM";
+    break;
+  default:
+    assert(0 && "Unreachable code!");
+  }
+
+  for (uid = 0; uid < numUIDs; uid++) {
+    // filter out intrinsics
+    if (!NumberedInstructions[uid]->TheDef->isSubClassOf(instClass))
+      continue;
+
+    if (populateInstruction(*NumberedInstructions[uid], TargetName))
+      Opcodes.push_back(uid);
+  }
+
+  // Special handling for the ARM chip, which supports two modes of execution.
+  // This branch handles the Thumb opcodes.
+  if (TargetName == TARGET_ARM) {
+    for (uid = 0; uid < numUIDs; uid++) {
+      // filter out intrinsics
+      if (!NumberedInstructions[uid]->TheDef->isSubClassOf("InstARM")
+          && !NumberedInstructions[uid]->TheDef->isSubClassOf("InstThumb"))
+        continue;
+
+      if (populateInstruction(*NumberedInstructions[uid], TARGET_THUMB))
+        Opcodes2.push_back(uid);
+    }
+  }
+}
+
+// Emits disassembler code for instruction decoding.  This delegates to the
+// FilterChooser instance to do the heavy lifting.
+void ARMDecoderEmitter::ARMDEBackend::emit(raw_ostream &o) {
+  switch (TargetName) {
+  case TARGET_ARM:
+    Frontend.EmitSourceFileHeader("ARM/Thumb Decoders", o);
+    break;
+  default:
+    assert(0 && "Unreachable code!");
+  }
+
+  o << "#include \"llvm/System/DataTypes.h\"\n";
+  o << "#include <assert.h>\n";
+  o << '\n';
+  o << "namespace llvm {\n\n";
+
+  FilterChooser::setTargetName(TargetName);
+
+  switch (TargetName) {
+  case TARGET_ARM: {
+    // Emit common utility and ARM ISA decoder.
+    FC = new FilterChooser(NumberedInstructions, Opcodes);
+    // Reset indentation level.
+    unsigned Indentation = 0;
+    FC->emitTop(o, Indentation);
+    delete FC;
+
+    // Emit Thumb ISA decoder as well.
+    FilterChooser::setTargetName(TARGET_THUMB);
+    FC = new FilterChooser(NumberedInstructions, Opcodes2);
+    // Reset indentation level.
+    Indentation = 0;
+    FC->emitBot(o, Indentation);
+    break;
+  }
+  default:
+    assert(0 && "Unreachable code!");
+  }
+
+  o << "\n} // End llvm namespace \n";
+}
+
+/////////////////////////
+//  Backend interface  //
+/////////////////////////
+
+void ARMDecoderEmitter::initBackend()
+{
+    Backend = new ARMDEBackend(*this);
+}
+
+void ARMDecoderEmitter::run(raw_ostream &o)
+{
+  Backend->emit(o);
+}
+
+void ARMDecoderEmitter::shutdownBackend()
+{
+  delete Backend;
+  Backend = NULL;
+}
diff --git a/src/LLVM/utils/TableGen/ARMDecoderEmitter.h b/src/LLVM/utils/TableGen/ARMDecoderEmitter.h
new file mode 100644
index 0000000..571a947
--- /dev/null
+++ b/src/LLVM/utils/TableGen/ARMDecoderEmitter.h
@@ -0,0 +1,50 @@
+//===------------ ARMDecoderEmitter.h - Decoder Generator -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is part of the ARM Disassembler.
+// It contains the tablegen backend declaration ARMDecoderEmitter.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ARMDECODEREMITTER_H
+#define ARMDECODEREMITTER_H
+
+#include "TableGenBackend.h"
+
+#include "llvm/System/DataTypes.h"
+
+namespace llvm {
+
+class ARMDecoderEmitter : public TableGenBackend {
+  RecordKeeper &Records;
+public:
+  ARMDecoderEmitter(RecordKeeper &R) : Records(R) {
+    initBackend();
+  }
+    
+  ~ARMDecoderEmitter() {
+    shutdownBackend();
+  }
+
+  // run - Output the code emitter
+  void run(raw_ostream &o);
+    
+private:
+  // Helper class for ARMDecoderEmitter.
+  class ARMDEBackend;
+
+  ARMDEBackend *Backend;
+    
+  void initBackend();
+  void shutdownBackend();
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/src/LLVM/utils/TableGen/AsmMatcherEmitter.cpp b/src/LLVM/utils/TableGen/AsmMatcherEmitter.cpp
new file mode 100644
index 0000000..08a430d
--- /dev/null
+++ b/src/LLVM/utils/TableGen/AsmMatcherEmitter.cpp
@@ -0,0 +1,1803 @@
+//===- AsmMatcherEmitter.cpp - Generate an assembly matcher ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend emits a target specifier matcher for converting parsed
+// assembly operands in the MCInst structures.
+//
+// The input to the target specific matcher is a list of literal tokens and
+// operands. The target specific parser should generally eliminate any syntax
+// which is not relevant for matching; for example, comma tokens should have
+// already been consumed and eliminated by the parser. Most instructions will
+// end up with a single literal token (the instruction name) and some number of
+// operands.
+//
+// Some example inputs, for X86:
+//   'addl' (immediate ...) (register ...)
+//   'add' (immediate ...) (memory ...)
+//   'call' '*' %epc 
+//
+// The assembly matcher is responsible for converting this input into a precise
+// machine instruction (i.e., an instruction with a well defined encoding). This
+// mapping has several properties which complicate matching:
+//
+//  - It may be ambiguous; many architectures can legally encode particular
+//    variants of an instruction in different ways (for example, using a smaller
+//    encoding for small immediates). Such ambiguities should never be
+//    arbitrarily resolved by the assembler, the assembler is always responsible
+//    for choosing the "best" available instruction.
+//
+//  - It may depend on the subtarget or the assembler context. Instructions
+//    which are invalid for the current mode, but otherwise unambiguous (e.g.,
+//    an SSE instruction in a file being assembled for i486) should be accepted
+//    and rejected by the assembler front end. However, if the proper encoding
+//    for an instruction is dependent on the assembler context then the matcher
+//    is responsible for selecting the correct machine instruction for the
+//    current mode.
+//
+// The core matching algorithm attempts to exploit the regularity in most
+// instruction sets to quickly determine the set of possibly matching
+// instructions, and the simplify the generated code. Additionally, this helps
+// to ensure that the ambiguities are intentionally resolved by the user.
+//
+// The matching is divided into two distinct phases:
+//
+//   1. Classification: Each operand is mapped to the unique set which (a)
+//      contains it, and (b) is the largest such subset for which a single
+//      instruction could match all members.
+//
+//      For register classes, we can generate these subgroups automatically. For
+//      arbitrary operands, we expect the user to define the classes and their
+//      relations to one another (for example, 8-bit signed immediates as a
+//      subset of 32-bit immediates).
+//
+//      By partitioning the operands in this way, we guarantee that for any
+//      tuple of classes, any single instruction must match either all or none
+//      of the sets of operands which could classify to that tuple.
+//
+//      In addition, the subset relation amongst classes induces a partial order
+//      on such tuples, which we use to resolve ambiguities.
+//
+//      FIXME: What do we do if a crazy case shows up where this is the wrong
+//      resolution?
+//
+//   2. The input can now be treated as a tuple of classes (static tokens are
+//      simple singleton sets). Each such tuple should generally map to a single
+//      instruction (we currently ignore cases where this isn't true, whee!!!),
+//      which we can emit a simple matcher for.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AsmMatcherEmitter.h"
+#include "CodeGenTarget.h"
+#include "Record.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include <list>
+#include <map>
+#include <set>
+using namespace llvm;
+
+static cl::opt<std::string>
+MatchPrefix("match-prefix", cl::init(""),
+            cl::desc("Only match instructions with the given prefix"));
+
+/// FlattenVariants - Flatten an .td file assembly string by selecting the
+/// variant at index \arg N.
+static std::string FlattenVariants(const std::string &AsmString,
+                                   unsigned N) {
+  StringRef Cur = AsmString;
+  std::string Res = "";
+  
+  for (;;) {
+    // Find the start of the next variant string.
+    size_t VariantsStart = 0;
+    for (size_t e = Cur.size(); VariantsStart != e; ++VariantsStart)
+      if (Cur[VariantsStart] == '{' && 
+          (VariantsStart == 0 || (Cur[VariantsStart-1] != '$' &&
+                                  Cur[VariantsStart-1] != '\\')))
+        break;
+
+    // Add the prefix to the result.
+    Res += Cur.slice(0, VariantsStart);
+    if (VariantsStart == Cur.size())
+      break;
+
+    ++VariantsStart; // Skip the '{'.
+
+    // Scan to the end of the variants string.
+    size_t VariantsEnd = VariantsStart;
+    unsigned NestedBraces = 1;
+    for (size_t e = Cur.size(); VariantsEnd != e; ++VariantsEnd) {
+      if (Cur[VariantsEnd] == '}' && Cur[VariantsEnd-1] != '\\') {
+        if (--NestedBraces == 0)
+          break;
+      } else if (Cur[VariantsEnd] == '{')
+        ++NestedBraces;
+    }
+
+    // Select the Nth variant (or empty).
+    StringRef Selection = Cur.slice(VariantsStart, VariantsEnd);
+    for (unsigned i = 0; i != N; ++i)
+      Selection = Selection.split('|').second;
+    Res += Selection.split('|').first;
+
+    assert(VariantsEnd != Cur.size() && 
+           "Unterminated variants in assembly string!");
+    Cur = Cur.substr(VariantsEnd + 1);
+  } 
+
+  return Res;
+}
+
+/// TokenizeAsmString - Tokenize a simplified assembly string.
+static void TokenizeAsmString(StringRef AsmString, 
+                              SmallVectorImpl<StringRef> &Tokens) {
+  unsigned Prev = 0;
+  bool InTok = true;
+  for (unsigned i = 0, e = AsmString.size(); i != e; ++i) {
+    switch (AsmString[i]) {
+    case '[':
+    case ']':
+    case '*':
+    case '!':
+    case ' ':
+    case '\t':
+    case ',':
+      if (InTok) {
+        Tokens.push_back(AsmString.slice(Prev, i));
+        InTok = false;
+      }
+      if (!isspace(AsmString[i]) && AsmString[i] != ',')
+        Tokens.push_back(AsmString.substr(i, 1));
+      Prev = i + 1;
+      break;
+      
+    case '\\':
+      if (InTok) {
+        Tokens.push_back(AsmString.slice(Prev, i));
+        InTok = false;
+      }
+      ++i;
+      assert(i != AsmString.size() && "Invalid quoted character");
+      Tokens.push_back(AsmString.substr(i, 1));
+      Prev = i + 1;
+      break;
+
+    case '$': {
+      // If this isn't "${", treat like a normal token.
+      if (i + 1 == AsmString.size() || AsmString[i + 1] != '{') {
+        if (InTok) {
+          Tokens.push_back(AsmString.slice(Prev, i));
+          InTok = false;
+        }
+        Prev = i;
+        break;
+      }
+
+      if (InTok) {
+        Tokens.push_back(AsmString.slice(Prev, i));
+        InTok = false;
+      }
+
+      StringRef::iterator End =
+        std::find(AsmString.begin() + i, AsmString.end(), '}');
+      assert(End != AsmString.end() && "Missing brace in operand reference!");
+      size_t EndPos = End - AsmString.begin();
+      Tokens.push_back(AsmString.slice(i, EndPos+1));
+      Prev = EndPos + 1;
+      i = EndPos;
+      break;
+    }
+
+    default:
+      InTok = true;
+    }
+  }
+  if (InTok && Prev != AsmString.size())
+    Tokens.push_back(AsmString.substr(Prev));
+}
+
+static bool IsAssemblerInstruction(StringRef Name,
+                                   const CodeGenInstruction &CGI, 
+                                   const SmallVectorImpl<StringRef> &Tokens) {
+  // Ignore "codegen only" instructions.
+  if (CGI.TheDef->getValueAsBit("isCodeGenOnly"))
+    return false;
+
+  // Ignore pseudo ops.
+  //
+  // FIXME: This is a hack; can we convert these instructions to set the
+  // "codegen only" bit instead?
+  if (const RecordVal *Form = CGI.TheDef->getValue("Form"))
+    if (Form->getValue()->getAsString() == "Pseudo")
+      return false;
+
+  // Ignore "Int_*" and "*_Int" instructions, which are internal aliases.
+  //
+  // FIXME: This is a total hack.
+  if (StringRef(Name).startswith("Int_") || StringRef(Name).endswith("_Int"))
+    return false;
+
+  // Ignore instructions with no .s string.
+  //
+  // FIXME: What are these?
+  if (CGI.AsmString.empty())
+    return false;
+
+  // FIXME: Hack; ignore any instructions with a newline in them.
+  if (std::find(CGI.AsmString.begin(), 
+                CGI.AsmString.end(), '\n') != CGI.AsmString.end())
+    return false;
+  
+  // Ignore instructions with attributes, these are always fake instructions for
+  // simplifying codegen.
+  //
+  // FIXME: Is this true?
+  //
+  // Also, check for instructions which reference the operand multiple times;
+  // this implies a constraint we would not honor.
+  std::set<std::string> OperandNames;
+  for (unsigned i = 1, e = Tokens.size(); i < e; ++i) {
+    if (Tokens[i][0] == '$' && 
+        std::find(Tokens[i].begin(), 
+                  Tokens[i].end(), ':') != Tokens[i].end()) {
+      DEBUG({
+          errs() << "warning: '" << Name << "': "
+                 << "ignoring instruction; operand with attribute '" 
+                 << Tokens[i] << "'\n";
+        });
+      return false;
+    }
+
+    if (Tokens[i][0] == '$' && !OperandNames.insert(Tokens[i]).second) {
+      std::string Err = "'" + Name.str() + "': " +
+        "invalid assembler instruction; tied operand '" + Tokens[i].str() + "'";
+      throw TGError(CGI.TheDef->getLoc(), Err);
+    }
+  }
+
+  return true;
+}
+
+namespace {
+
+struct SubtargetFeatureInfo;
+
+/// ClassInfo - Helper class for storing the information about a particular
+/// class of operands which can be matched.
+struct ClassInfo {
+  enum ClassInfoKind {
+    /// Invalid kind, for use as a sentinel value.
+    Invalid = 0,
+
+    /// The class for a particular token.
+    Token,
+
+    /// The (first) register class, subsequent register classes are
+    /// RegisterClass0+1, and so on.
+    RegisterClass0,
+
+    /// The (first) user defined class, subsequent user defined classes are
+    /// UserClass0+1, and so on.
+    UserClass0 = 1<<16
+  };
+
+  /// Kind - The class kind, which is either a predefined kind, or (UserClass0 +
+  /// N) for the Nth user defined class.
+  unsigned Kind;
+
+  /// SuperClasses - The super classes of this class. Note that for simplicities
+  /// sake user operands only record their immediate super class, while register
+  /// operands include all superclasses.
+  std::vector<ClassInfo*> SuperClasses;
+
+  /// Name - The full class name, suitable for use in an enum.
+  std::string Name;
+
+  /// ClassName - The unadorned generic name for this class (e.g., Token).
+  std::string ClassName;
+
+  /// ValueName - The name of the value this class represents; for a token this
+  /// is the literal token string, for an operand it is the TableGen class (or
+  /// empty if this is a derived class).
+  std::string ValueName;
+
+  /// PredicateMethod - The name of the operand method to test whether the
+  /// operand matches this class; this is not valid for Token or register kinds.
+  std::string PredicateMethod;
+
+  /// RenderMethod - The name of the operand method to add this operand to an
+  /// MCInst; this is not valid for Token or register kinds.
+  std::string RenderMethod;
+
+  /// For register classes, the records for all the registers in this class.
+  std::set<Record*> Registers;
+
+public:
+  /// isRegisterClass() - Check if this is a register class.
+  bool isRegisterClass() const {
+    return Kind >= RegisterClass0 && Kind < UserClass0;
+  }
+
+  /// isUserClass() - Check if this is a user defined class.
+  bool isUserClass() const {
+    return Kind >= UserClass0;
+  }
+
+  /// isRelatedTo - Check whether this class is "related" to \arg RHS. Classes
+  /// are related if they are in the same class hierarchy.
+  bool isRelatedTo(const ClassInfo &RHS) const {
+    // Tokens are only related to tokens.
+    if (Kind == Token || RHS.Kind == Token)
+      return Kind == Token && RHS.Kind == Token;
+
+    // Registers classes are only related to registers classes, and only if
+    // their intersection is non-empty.
+    if (isRegisterClass() || RHS.isRegisterClass()) {
+      if (!isRegisterClass() || !RHS.isRegisterClass())
+        return false;
+
+      std::set<Record*> Tmp;
+      std::insert_iterator< std::set<Record*> > II(Tmp, Tmp.begin());
+      std::set_intersection(Registers.begin(), Registers.end(), 
+                            RHS.Registers.begin(), RHS.Registers.end(),
+                            II);
+
+      return !Tmp.empty();
+    }
+
+    // Otherwise we have two users operands; they are related if they are in the
+    // same class hierarchy.
+    //
+    // FIXME: This is an oversimplification, they should only be related if they
+    // intersect, however we don't have that information.
+    assert(isUserClass() && RHS.isUserClass() && "Unexpected class!");
+    const ClassInfo *Root = this;
+    while (!Root->SuperClasses.empty())
+      Root = Root->SuperClasses.front();
+
+    const ClassInfo *RHSRoot = &RHS;
+    while (!RHSRoot->SuperClasses.empty())
+      RHSRoot = RHSRoot->SuperClasses.front();
+    
+    return Root == RHSRoot;
+  }
+
+  /// isSubsetOf - Test whether this class is a subset of \arg RHS; 
+  bool isSubsetOf(const ClassInfo &RHS) const {
+    // This is a subset of RHS if it is the same class...
+    if (this == &RHS)
+      return true;
+
+    // ... or if any of its super classes are a subset of RHS.
+    for (std::vector<ClassInfo*>::const_iterator it = SuperClasses.begin(),
+           ie = SuperClasses.end(); it != ie; ++it)
+      if ((*it)->isSubsetOf(RHS))
+        return true;
+
+    return false;
+  }
+
+  /// operator< - Compare two classes.
+  bool operator<(const ClassInfo &RHS) const {
+    if (this == &RHS)
+      return false;
+
+    // Unrelated classes can be ordered by kind.
+    if (!isRelatedTo(RHS))
+      return Kind < RHS.Kind;
+
+    switch (Kind) {
+    case Invalid:
+      assert(0 && "Invalid kind!");
+    case Token:
+      // Tokens are comparable by value.
+      //
+      // FIXME: Compare by enum value.
+      return ValueName < RHS.ValueName;
+
+    default:
+      // This class preceeds the RHS if it is a proper subset of the RHS.
+      if (isSubsetOf(RHS))
+        return true;
+      if (RHS.isSubsetOf(*this))
+        return false;
+
+      // Otherwise, order by name to ensure we have a total ordering.
+      return ValueName < RHS.ValueName;
+    }
+  }
+};
+
+/// InstructionInfo - Helper class for storing the necessary information for an
+/// instruction which is capable of being matched.
+struct InstructionInfo {
+  struct Operand {
+    /// The unique class instance this operand should match.
+    ClassInfo *Class;
+
+    /// The original operand this corresponds to, if any.
+    const CodeGenInstruction::OperandInfo *OperandInfo;
+  };
+
+  /// InstrName - The target name for this instruction.
+  std::string InstrName;
+
+  /// Instr - The instruction this matches.
+  const CodeGenInstruction *Instr;
+
+  /// AsmString - The assembly string for this instruction (with variants
+  /// removed).
+  std::string AsmString;
+
+  /// Tokens - The tokenized assembly pattern that this instruction matches.
+  SmallVector<StringRef, 4> Tokens;
+
+  /// Operands - The operands that this instruction matches.
+  SmallVector<Operand, 4> Operands;
+
+  /// Predicates - The required subtarget features to match this instruction.
+  SmallVector<SubtargetFeatureInfo*, 4> RequiredFeatures;
+
+  /// ConversionFnKind - The enum value which is passed to the generated
+  /// ConvertToMCInst to convert parsed operands into an MCInst for this
+  /// function.
+  std::string ConversionFnKind;
+
+  /// operator< - Compare two instructions.
+  bool operator<(const InstructionInfo &RHS) const {
+    if (Operands.size() != RHS.Operands.size())
+      return Operands.size() < RHS.Operands.size();
+
+    // Compare lexicographically by operand. The matcher validates that other
+    // orderings wouldn't be ambiguous using \see CouldMatchAmiguouslyWith().
+    for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
+      if (*Operands[i].Class < *RHS.Operands[i].Class)
+        return true;
+      if (*RHS.Operands[i].Class < *Operands[i].Class)
+        return false;
+    }
+
+    return false;
+  }
+
+  /// CouldMatchAmiguouslyWith - Check whether this instruction could
+  /// ambiguously match the same set of operands as \arg RHS (without being a
+  /// strictly superior match).
+  bool CouldMatchAmiguouslyWith(const InstructionInfo &RHS) {
+    // The number of operands is unambiguous.
+    if (Operands.size() != RHS.Operands.size())
+      return false;
+
+    // Otherwise, make sure the ordering of the two instructions is unambiguous
+    // by checking that either (a) a token or operand kind discriminates them,
+    // or (b) the ordering among equivalent kinds is consistent.
+
+    // Tokens and operand kinds are unambiguous (assuming a correct target
+    // specific parser).
+    for (unsigned i = 0, e = Operands.size(); i != e; ++i)
+      if (Operands[i].Class->Kind != RHS.Operands[i].Class->Kind ||
+          Operands[i].Class->Kind == ClassInfo::Token)
+        if (*Operands[i].Class < *RHS.Operands[i].Class ||
+            *RHS.Operands[i].Class < *Operands[i].Class)
+          return false;
+    
+    // Otherwise, this operand could commute if all operands are equivalent, or
+    // there is a pair of operands that compare less than and a pair that
+    // compare greater than.
+    bool HasLT = false, HasGT = false;
+    for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
+      if (*Operands[i].Class < *RHS.Operands[i].Class)
+        HasLT = true;
+      if (*RHS.Operands[i].Class < *Operands[i].Class)
+        HasGT = true;
+    }
+
+    return !(HasLT ^ HasGT);
+  }
+
+public:
+  void dump();
+};
+
+/// SubtargetFeatureInfo - Helper class for storing information on a subtarget
+/// feature which participates in instruction matching.
+struct SubtargetFeatureInfo {
+  /// \brief The predicate record for this feature.
+  Record *TheDef;
+
+  /// \brief An unique index assigned to represent this feature.
+  unsigned Index;
+
+  /// \brief The name of the enumerated constant identifying this feature.
+  std::string EnumName;
+};
+
+class AsmMatcherInfo {
+public:
+  /// The tablegen AsmParser record.
+  Record *AsmParser;
+
+  /// The AsmParser "CommentDelimiter" value.
+  std::string CommentDelimiter;
+
+  /// The AsmParser "RegisterPrefix" value.
+  std::string RegisterPrefix;
+
+  /// The classes which are needed for matching.
+  std::vector<ClassInfo*> Classes;
+  
+  /// The information on the instruction to match.
+  std::vector<InstructionInfo*> Instructions;
+
+  /// Map of Register records to their class information.
+  std::map<Record*, ClassInfo*> RegisterClasses;
+
+  /// Map of Predicate records to their subtarget information.
+  std::map<Record*, SubtargetFeatureInfo*> SubtargetFeatures;
+
+private:
+  /// Map of token to class information which has already been constructed.
+  std::map<std::string, ClassInfo*> TokenClasses;
+
+  /// Map of RegisterClass records to their class information.
+  std::map<Record*, ClassInfo*> RegisterClassClasses;
+
+  /// Map of AsmOperandClass records to their class information.
+  std::map<Record*, ClassInfo*> AsmOperandClasses;
+
+private:
+  /// getTokenClass - Lookup or create the class for the given token.
+  ClassInfo *getTokenClass(StringRef Token);
+
+  /// getOperandClass - Lookup or create the class for the given operand.
+  ClassInfo *getOperandClass(StringRef Token,
+                             const CodeGenInstruction::OperandInfo &OI);
+
+  /// getSubtargetFeature - Lookup or create the subtarget feature info for the
+  /// given operand.
+  SubtargetFeatureInfo *getSubtargetFeature(Record *Def) {
+    assert(Def->isSubClassOf("Predicate") && "Invalid predicate type!");
+
+    SubtargetFeatureInfo *&Entry = SubtargetFeatures[Def];
+    if (!Entry) {
+      Entry = new SubtargetFeatureInfo;
+      Entry->TheDef = Def;
+      Entry->Index = SubtargetFeatures.size() - 1;
+      Entry->EnumName = "Feature_" + Def->getName();
+      assert(Entry->Index < 32 && "Too many subtarget features!");
+    }
+
+    return Entry;
+  }
+
+  /// BuildRegisterClasses - Build the ClassInfo* instances for register
+  /// classes.
+  void BuildRegisterClasses(CodeGenTarget &Target, 
+                            std::set<std::string> &SingletonRegisterNames);
+
+  /// BuildOperandClasses - Build the ClassInfo* instances for user defined
+  /// operand classes.
+  void BuildOperandClasses(CodeGenTarget &Target);
+
+public:
+  AsmMatcherInfo(Record *_AsmParser);
+
+  /// BuildInfo - Construct the various tables used during matching.
+  void BuildInfo(CodeGenTarget &Target);
+};
+
+}
+
+void InstructionInfo::dump() {
+  errs() << InstrName << " -- " << "flattened:\"" << AsmString << '\"'
+         << ", tokens:[";
+  for (unsigned i = 0, e = Tokens.size(); i != e; ++i) {
+    errs() << Tokens[i];
+    if (i + 1 != e)
+      errs() << ", ";
+  }
+  errs() << "]\n";
+
+  for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
+    Operand &Op = Operands[i];
+    errs() << "  op[" << i << "] = " << Op.Class->ClassName << " - ";
+    if (Op.Class->Kind == ClassInfo::Token) {
+      errs() << '\"' << Tokens[i] << "\"\n";
+      continue;
+    }
+
+    if (!Op.OperandInfo) {
+      errs() << "(singleton register)\n";
+      continue;
+    }
+
+    const CodeGenInstruction::OperandInfo &OI = *Op.OperandInfo;
+    errs() << OI.Name << " " << OI.Rec->getName()
+           << " (" << OI.MIOperandNo << ", " << OI.MINumOperands << ")\n";
+  }
+}
+
+static std::string getEnumNameForToken(StringRef Str) {
+  std::string Res;
+  
+  for (StringRef::iterator it = Str.begin(), ie = Str.end(); it != ie; ++it) {
+    switch (*it) {
+    case '*': Res += "_STAR_"; break;
+    case '%': Res += "_PCT_"; break;
+    case ':': Res += "_COLON_"; break;
+
+    default:
+      if (isalnum(*it))  {
+        Res += *it;
+      } else {
+        Res += "_" + utostr((unsigned) *it) + "_";
+      }
+    }
+  }
+
+  return Res;
+}
+
+/// getRegisterRecord - Get the register record for \arg name, or 0.
+static Record *getRegisterRecord(CodeGenTarget &Target, StringRef Name) {
+  for (unsigned i = 0, e = Target.getRegisters().size(); i != e; ++i) {
+    const CodeGenRegister &Reg = Target.getRegisters()[i];
+    if (Name == Reg.TheDef->getValueAsString("AsmName"))
+      return Reg.TheDef;
+  }
+
+  return 0;
+}
+
+ClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) {
+  ClassInfo *&Entry = TokenClasses[Token];
+  
+  if (!Entry) {
+    Entry = new ClassInfo();
+    Entry->Kind = ClassInfo::Token;
+    Entry->ClassName = "Token";
+    Entry->Name = "MCK_" + getEnumNameForToken(Token);
+    Entry->ValueName = Token;
+    Entry->PredicateMethod = "<invalid>";
+    Entry->RenderMethod = "<invalid>";
+    Classes.push_back(Entry);
+  }
+
+  return Entry;
+}
+
+ClassInfo *
+AsmMatcherInfo::getOperandClass(StringRef Token,
+                                const CodeGenInstruction::OperandInfo &OI) {
+  if (OI.Rec->isSubClassOf("RegisterClass")) {
+    ClassInfo *CI = RegisterClassClasses[OI.Rec];
+
+    if (!CI) {
+      PrintError(OI.Rec->getLoc(), "register class has no class info!");
+      throw std::string("ERROR: Missing register class!");
+    }
+
+    return CI;
+  }
+
+  assert(OI.Rec->isSubClassOf("Operand") && "Unexpected operand!");
+  Record *MatchClass = OI.Rec->getValueAsDef("ParserMatchClass");
+  ClassInfo *CI = AsmOperandClasses[MatchClass];
+
+  if (!CI) {
+    PrintError(OI.Rec->getLoc(), "operand has no match class!");
+    throw std::string("ERROR: Missing match class!");
+  }
+
+  return CI;
+}
+
+void AsmMatcherInfo::BuildRegisterClasses(CodeGenTarget &Target,
+                                          std::set<std::string>
+                                            &SingletonRegisterNames) {
+  std::vector<CodeGenRegisterClass> RegisterClasses;
+  std::vector<CodeGenRegister> Registers;
+
+  RegisterClasses = Target.getRegisterClasses();
+  Registers = Target.getRegisters();
+
+  // The register sets used for matching.
+  std::set< std::set<Record*> > RegisterSets;
+
+  // Gather the defined sets.  
+  for (std::vector<CodeGenRegisterClass>::iterator it = RegisterClasses.begin(),
+         ie = RegisterClasses.end(); it != ie; ++it)
+    RegisterSets.insert(std::set<Record*>(it->Elements.begin(),
+                                          it->Elements.end()));
+
+  // Add any required singleton sets.
+  for (std::set<std::string>::iterator it = SingletonRegisterNames.begin(),
+         ie = SingletonRegisterNames.end(); it != ie; ++it)
+    if (Record *Rec = getRegisterRecord(Target, *it))
+      RegisterSets.insert(std::set<Record*>(&Rec, &Rec + 1));
+         
+  // Introduce derived sets where necessary (when a register does not determine
+  // a unique register set class), and build the mapping of registers to the set
+  // they should classify to.
+  std::map<Record*, std::set<Record*> > RegisterMap;
+  for (std::vector<CodeGenRegister>::iterator it = Registers.begin(),
+         ie = Registers.end(); it != ie; ++it) {
+    CodeGenRegister &CGR = *it;
+    // Compute the intersection of all sets containing this register.
+    std::set<Record*> ContainingSet;
+    
+    for (std::set< std::set<Record*> >::iterator it = RegisterSets.begin(),
+           ie = RegisterSets.end(); it != ie; ++it) {
+      if (!it->count(CGR.TheDef))
+        continue;
+
+      if (ContainingSet.empty()) {
+        ContainingSet = *it;
+      } else {
+        std::set<Record*> Tmp;
+        std::swap(Tmp, ContainingSet);
+        std::insert_iterator< std::set<Record*> > II(ContainingSet,
+                                                     ContainingSet.begin());
+        std::set_intersection(Tmp.begin(), Tmp.end(), it->begin(), it->end(),
+                              II);
+      }
+    }
+
+    if (!ContainingSet.empty()) {
+      RegisterSets.insert(ContainingSet);
+      RegisterMap.insert(std::make_pair(CGR.TheDef, ContainingSet));
+    }
+  }
+
+  // Construct the register classes.
+  std::map<std::set<Record*>, ClassInfo*> RegisterSetClasses;
+  unsigned Index = 0;
+  for (std::set< std::set<Record*> >::iterator it = RegisterSets.begin(),
+         ie = RegisterSets.end(); it != ie; ++it, ++Index) {
+    ClassInfo *CI = new ClassInfo();
+    CI->Kind = ClassInfo::RegisterClass0 + Index;
+    CI->ClassName = "Reg" + utostr(Index);
+    CI->Name = "MCK_Reg" + utostr(Index);
+    CI->ValueName = "";
+    CI->PredicateMethod = ""; // unused
+    CI->RenderMethod = "addRegOperands";
+    CI->Registers = *it;
+    Classes.push_back(CI);
+    RegisterSetClasses.insert(std::make_pair(*it, CI));
+  }
+
+  // Find the superclasses; we could compute only the subgroup lattice edges,
+  // but there isn't really a point.
+  for (std::set< std::set<Record*> >::iterator it = RegisterSets.begin(),
+         ie = RegisterSets.end(); it != ie; ++it) {
+    ClassInfo *CI = RegisterSetClasses[*it];
+    for (std::set< std::set<Record*> >::iterator it2 = RegisterSets.begin(),
+           ie2 = RegisterSets.end(); it2 != ie2; ++it2)
+      if (*it != *it2 && 
+          std::includes(it2->begin(), it2->end(), it->begin(), it->end()))
+        CI->SuperClasses.push_back(RegisterSetClasses[*it2]);
+  }
+
+  // Name the register classes which correspond to a user defined RegisterClass.
+  for (std::vector<CodeGenRegisterClass>::iterator it = RegisterClasses.begin(),
+         ie = RegisterClasses.end(); it != ie; ++it) {
+    ClassInfo *CI = RegisterSetClasses[std::set<Record*>(it->Elements.begin(),
+                                                         it->Elements.end())];
+    if (CI->ValueName.empty()) {
+      CI->ClassName = it->getName();
+      CI->Name = "MCK_" + it->getName();
+      CI->ValueName = it->getName();
+    } else
+      CI->ValueName = CI->ValueName + "," + it->getName();
+
+    RegisterClassClasses.insert(std::make_pair(it->TheDef, CI));
+  }
+
+  // Populate the map for individual registers.
+  for (std::map<Record*, std::set<Record*> >::iterator it = RegisterMap.begin(),
+         ie = RegisterMap.end(); it != ie; ++it)
+    this->RegisterClasses[it->first] = RegisterSetClasses[it->second];
+
+  // Name the register classes which correspond to singleton registers.
+  for (std::set<std::string>::iterator it = SingletonRegisterNames.begin(),
+         ie = SingletonRegisterNames.end(); it != ie; ++it) {
+    if (Record *Rec = getRegisterRecord(Target, *it)) {
+      ClassInfo *CI = this->RegisterClasses[Rec];
+      assert(CI && "Missing singleton register class info!");
+
+      if (CI->ValueName.empty()) {
+        CI->ClassName = Rec->getName();
+        CI->Name = "MCK_" + Rec->getName();
+        CI->ValueName = Rec->getName();
+      } else
+        CI->ValueName = CI->ValueName + "," + Rec->getName();
+    }
+  }
+}
+
+void AsmMatcherInfo::BuildOperandClasses(CodeGenTarget &Target) {
+  std::vector<Record*> AsmOperands;
+  AsmOperands = Records.getAllDerivedDefinitions("AsmOperandClass");
+
+  // Pre-populate AsmOperandClasses map.
+  for (std::vector<Record*>::iterator it = AsmOperands.begin(), 
+         ie = AsmOperands.end(); it != ie; ++it)
+    AsmOperandClasses[*it] = new ClassInfo();
+
+  unsigned Index = 0;
+  for (std::vector<Record*>::iterator it = AsmOperands.begin(), 
+         ie = AsmOperands.end(); it != ie; ++it, ++Index) {
+    ClassInfo *CI = AsmOperandClasses[*it];
+    CI->Kind = ClassInfo::UserClass0 + Index;
+
+    ListInit *Supers = (*it)->getValueAsListInit("SuperClasses");
+    for (unsigned i = 0, e = Supers->getSize(); i != e; ++i) {
+      DefInit *DI = dynamic_cast<DefInit*>(Supers->getElement(i));
+      if (!DI) {
+        PrintError((*it)->getLoc(), "Invalid super class reference!");
+        continue;
+      }
+
+      ClassInfo *SC = AsmOperandClasses[DI->getDef()];
+      if (!SC)
+        PrintError((*it)->getLoc(), "Invalid super class reference!");
+      else
+        CI->SuperClasses.push_back(SC);
+    }
+    CI->ClassName = (*it)->getValueAsString("Name");
+    CI->Name = "MCK_" + CI->ClassName;
+    CI->ValueName = (*it)->getName();
+
+    // Get or construct the predicate method name.
+    Init *PMName = (*it)->getValueInit("PredicateMethod");
+    if (StringInit *SI = dynamic_cast<StringInit*>(PMName)) {
+      CI->PredicateMethod = SI->getValue();
+    } else {
+      assert(dynamic_cast<UnsetInit*>(PMName) && 
+             "Unexpected PredicateMethod field!");
+      CI->PredicateMethod = "is" + CI->ClassName;
+    }
+
+    // Get or construct the render method name.
+    Init *RMName = (*it)->getValueInit("RenderMethod");
+    if (StringInit *SI = dynamic_cast<StringInit*>(RMName)) {
+      CI->RenderMethod = SI->getValue();
+    } else {
+      assert(dynamic_cast<UnsetInit*>(RMName) &&
+             "Unexpected RenderMethod field!");
+      CI->RenderMethod = "add" + CI->ClassName + "Operands";
+    }
+
+    AsmOperandClasses[*it] = CI;
+    Classes.push_back(CI);
+  }
+}
+
+AsmMatcherInfo::AsmMatcherInfo(Record *_AsmParser) 
+  : AsmParser(_AsmParser),
+    CommentDelimiter(AsmParser->getValueAsString("CommentDelimiter")),
+    RegisterPrefix(AsmParser->getValueAsString("RegisterPrefix"))
+{
+}
+
+void AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) {
+  // Parse the instructions; we need to do this first so that we can gather the
+  // singleton register classes.
+  std::set<std::string> SingletonRegisterNames;
+  
+  const std::vector<const CodeGenInstruction*> &InstrList =
+    Target.getInstructionsByEnumValue();
+  
+  for (unsigned i = 0, e = InstrList.size(); i != e; ++i) {
+    const CodeGenInstruction &CGI = *InstrList[i];
+
+    if (!StringRef(CGI.TheDef->getName()).startswith(MatchPrefix))
+      continue;
+
+    OwningPtr<InstructionInfo> II(new InstructionInfo());
+    
+    II->InstrName = CGI.TheDef->getName();
+    II->Instr = &CGI;
+    II->AsmString = FlattenVariants(CGI.AsmString, 0);
+
+    // Remove comments from the asm string.
+    if (!CommentDelimiter.empty()) {
+      size_t Idx = StringRef(II->AsmString).find(CommentDelimiter);
+      if (Idx != StringRef::npos)
+        II->AsmString = II->AsmString.substr(0, Idx);
+    }
+
+    TokenizeAsmString(II->AsmString, II->Tokens);
+
+    // Ignore instructions which shouldn't be matched.
+    if (!IsAssemblerInstruction(CGI.TheDef->getName(), CGI, II->Tokens))
+      continue;
+
+    // Collect singleton registers, if used.
+    if (!RegisterPrefix.empty()) {
+      for (unsigned i = 0, e = II->Tokens.size(); i != e; ++i) {
+        if (II->Tokens[i].startswith(RegisterPrefix)) {
+          StringRef RegName = II->Tokens[i].substr(RegisterPrefix.size());
+          Record *Rec = getRegisterRecord(Target, RegName);
+          
+          if (!Rec) {
+            std::string Err = "unable to find register for '" + RegName.str() + 
+              "' (which matches register prefix)";
+            throw TGError(CGI.TheDef->getLoc(), Err);
+          }
+
+          SingletonRegisterNames.insert(RegName);
+        }
+      }
+    }
+
+    // Compute the require features.
+    ListInit *Predicates = CGI.TheDef->getValueAsListInit("Predicates");
+    for (unsigned i = 0, e = Predicates->getSize(); i != e; ++i) {
+      if (DefInit *Pred = dynamic_cast<DefInit*>(Predicates->getElement(i))) {
+        // Ignore OptForSize and OptForSpeed, they aren't really requirements,
+        // rather they are hints to isel.
+        //
+        // FIXME: Find better way to model this.
+        if (Pred->getDef()->getName() == "OptForSize" ||
+            Pred->getDef()->getName() == "OptForSpeed")
+          continue;
+
+        // FIXME: Total hack; for now, we just limit ourselves to In32BitMode
+        // and In64BitMode, because we aren't going to have the right feature
+        // masks for SSE and friends. We need to decide what we are going to do
+        // about CPU subtypes to implement this the right way.
+        if (Pred->getDef()->getName() != "In32BitMode" &&
+            Pred->getDef()->getName() != "In64BitMode")
+          continue;
+
+        II->RequiredFeatures.push_back(getSubtargetFeature(Pred->getDef()));
+      }
+    }
+
+    Instructions.push_back(II.take());
+  }
+
+  // Build info for the register classes.
+  BuildRegisterClasses(Target, SingletonRegisterNames);
+
+  // Build info for the user defined assembly operand classes.
+  BuildOperandClasses(Target);
+
+  // Build the instruction information.
+  for (std::vector<InstructionInfo*>::iterator it = Instructions.begin(),
+         ie = Instructions.end(); it != ie; ++it) {
+    InstructionInfo *II = *it;
+
+    for (unsigned i = 0, e = II->Tokens.size(); i != e; ++i) {
+      StringRef Token = II->Tokens[i];
+
+      // Check for singleton registers.
+      if (!RegisterPrefix.empty() && Token.startswith(RegisterPrefix)) {
+        StringRef RegName = II->Tokens[i].substr(RegisterPrefix.size());
+        InstructionInfo::Operand Op;
+        Op.Class = RegisterClasses[getRegisterRecord(Target, RegName)];
+        Op.OperandInfo = 0;
+        assert(Op.Class && Op.Class->Registers.size() == 1 &&
+               "Unexpected class for singleton register");
+        II->Operands.push_back(Op);
+        continue;
+      }
+
+      // Check for simple tokens.
+      if (Token[0] != '$') {
+        InstructionInfo::Operand Op;
+        Op.Class = getTokenClass(Token);
+        Op.OperandInfo = 0;
+        II->Operands.push_back(Op);
+        continue;
+      }
+
+      // Otherwise this is an operand reference.
+      StringRef OperandName;
+      if (Token[1] == '{')
+        OperandName = Token.substr(2, Token.size() - 3);
+      else
+        OperandName = Token.substr(1);
+
+      // Map this token to an operand. FIXME: Move elsewhere.
+      unsigned Idx;
+      try {
+        Idx = II->Instr->getOperandNamed(OperandName);
+      } catch(...) {
+        throw std::string("error: unable to find operand: '" + 
+                          OperandName.str() + "'");
+      }
+
+      // FIXME: This is annoying, the named operand may be tied (e.g.,
+      // XCHG8rm). What we want is the untied operand, which we now have to
+      // grovel for. Only worry about this for single entry operands, we have to
+      // clean this up anyway.
+      const CodeGenInstruction::OperandInfo *OI = &II->Instr->OperandList[Idx];
+      if (OI->Constraints[0].isTied()) {
+        unsigned TiedOp = OI->Constraints[0].getTiedOperand();
+
+        // The tied operand index is an MIOperand index, find the operand that
+        // contains it.
+        for (unsigned i = 0, e = II->Instr->OperandList.size(); i != e; ++i) {
+          if (II->Instr->OperandList[i].MIOperandNo == TiedOp) {
+            OI = &II->Instr->OperandList[i];
+            break;
+          }
+        }
+
+        assert(OI && "Unable to find tied operand target!");
+      }
+
+      InstructionInfo::Operand Op;
+      Op.Class = getOperandClass(Token, *OI);
+      Op.OperandInfo = OI;
+      II->Operands.push_back(Op);
+    }
+  }
+
+  // Reorder classes so that classes preceed super classes.
+  std::sort(Classes.begin(), Classes.end(), less_ptr<ClassInfo>());
+}
+
+static std::pair<unsigned, unsigned> *
+GetTiedOperandAtIndex(SmallVectorImpl<std::pair<unsigned, unsigned> > &List,
+                      unsigned Index) {
+  for (unsigned i = 0, e = List.size(); i != e; ++i)
+    if (Index == List[i].first)
+      return &List[i];
+
+  return 0;
+}
+
+static void EmitConvertToMCInst(CodeGenTarget &Target,
+                                std::vector<InstructionInfo*> &Infos,
+                                raw_ostream &OS) {
+  // Write the convert function to a separate stream, so we can drop it after
+  // the enum.
+  std::string ConvertFnBody;
+  raw_string_ostream CvtOS(ConvertFnBody);
+
+  // Function we have already generated.
+  std::set<std::string> GeneratedFns;
+
+  // Start the unified conversion function.
+
+  CvtOS << "static void ConvertToMCInst(ConversionKind Kind, MCInst &Inst, "
+        << "unsigned Opcode,\n"
+        << "                      const SmallVectorImpl<MCParsedAsmOperand*"
+        << "> &Operands) {\n";
+  CvtOS << "  Inst.setOpcode(Opcode);\n";
+  CvtOS << "  switch (Kind) {\n";
+  CvtOS << "  default:\n";
+
+  // Start the enum, which we will generate inline.
+
+  OS << "// Unified function for converting operants to MCInst instances.\n\n";
+  OS << "enum ConversionKind {\n";
+  
+  // TargetOperandClass - This is the target's operand class, like X86Operand.
+  std::string TargetOperandClass = Target.getName() + "Operand";
+  
+  for (std::vector<InstructionInfo*>::const_iterator it = Infos.begin(),
+         ie = Infos.end(); it != ie; ++it) {
+    InstructionInfo &II = **it;
+
+    // Order the (class) operands by the order to convert them into an MCInst.
+    SmallVector<std::pair<unsigned, unsigned>, 4> MIOperandList;
+    for (unsigned i = 0, e = II.Operands.size(); i != e; ++i) {
+      InstructionInfo::Operand &Op = II.Operands[i];
+      if (Op.OperandInfo)
+        MIOperandList.push_back(std::make_pair(Op.OperandInfo->MIOperandNo, i));
+    }
+
+    // Find any tied operands.
+    SmallVector<std::pair<unsigned, unsigned>, 4> TiedOperands;
+    for (unsigned i = 0, e = II.Instr->OperandList.size(); i != e; ++i) {
+      const CodeGenInstruction::OperandInfo &OpInfo = II.Instr->OperandList[i];
+      for (unsigned j = 0, e = OpInfo.Constraints.size(); j != e; ++j) {
+        const CodeGenInstruction::ConstraintInfo &CI = OpInfo.Constraints[j];
+        if (CI.isTied())
+          TiedOperands.push_back(std::make_pair(OpInfo.MIOperandNo + j,
+                                                CI.getTiedOperand()));
+      }
+    }
+
+    std::sort(MIOperandList.begin(), MIOperandList.end());
+
+    // Compute the total number of operands.
+    unsigned NumMIOperands = 0;
+    for (unsigned i = 0, e = II.Instr->OperandList.size(); i != e; ++i) {
+      const CodeGenInstruction::OperandInfo &OI = II.Instr->OperandList[i];
+      NumMIOperands = std::max(NumMIOperands, 
+                               OI.MIOperandNo + OI.MINumOperands);
+    }
+
+    // Build the conversion function signature.
+    std::string Signature = "Convert";
+    unsigned CurIndex = 0;
+    for (unsigned i = 0, e = MIOperandList.size(); i != e; ++i) {
+      InstructionInfo::Operand &Op = II.Operands[MIOperandList[i].second];
+      assert(CurIndex <= Op.OperandInfo->MIOperandNo &&
+             "Duplicate match for instruction operand!");
+      
+      // Skip operands which weren't matched by anything, this occurs when the
+      // .td file encodes "implicit" operands as explicit ones.
+      //
+      // FIXME: This should be removed from the MCInst structure.
+      for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex) {
+        std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands,
+                                                                   CurIndex);
+        if (!Tie)
+          Signature += "__Imp";
+        else
+          Signature += "__Tie" + utostr(Tie->second);
+      }
+
+      Signature += "__";
+
+      // Registers are always converted the same, don't duplicate the conversion
+      // function based on them.
+      //
+      // FIXME: We could generalize this based on the render method, if it
+      // mattered.
+      if (Op.Class->isRegisterClass())
+        Signature += "Reg";
+      else
+        Signature += Op.Class->ClassName;
+      Signature += utostr(Op.OperandInfo->MINumOperands);
+      Signature += "_" + utostr(MIOperandList[i].second);
+
+      CurIndex += Op.OperandInfo->MINumOperands;
+    }
+
+    // Add any trailing implicit operands.
+    for (; CurIndex != NumMIOperands; ++CurIndex) {
+      std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands,
+                                                                 CurIndex);
+      if (!Tie)
+        Signature += "__Imp";
+      else
+        Signature += "__Tie" + utostr(Tie->second);
+    }
+
+    II.ConversionFnKind = Signature;
+
+    // Check if we have already generated this signature.
+    if (!GeneratedFns.insert(Signature).second)
+      continue;
+
+    // If not, emit it now.
+
+    // Add to the enum list.
+    OS << "  " << Signature << ",\n";
+
+    // And to the convert function.
+    CvtOS << "  case " << Signature << ":\n";
+    CurIndex = 0;
+    for (unsigned i = 0, e = MIOperandList.size(); i != e; ++i) {
+      InstructionInfo::Operand &Op = II.Operands[MIOperandList[i].second];
+
+      // Add the implicit operands.
+      for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex) {
+        // See if this is a tied operand.
+        std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands,
+                                                                   CurIndex);
+
+        if (!Tie) {
+          // If not, this is some implicit operand. Just assume it is a register
+          // for now.
+          CvtOS << "    Inst.addOperand(MCOperand::CreateReg(0));\n";
+        } else {
+          // Copy the tied operand.
+          assert(Tie->first>Tie->second && "Tied operand preceeds its target!");
+          CvtOS << "    Inst.addOperand(Inst.getOperand("
+                << Tie->second << "));\n";
+        }
+      }
+
+      CvtOS << "    ((" << TargetOperandClass << "*)Operands["
+         << MIOperandList[i].second 
+         << "])->" << Op.Class->RenderMethod 
+         << "(Inst, " << Op.OperandInfo->MINumOperands << ");\n";
+      CurIndex += Op.OperandInfo->MINumOperands;
+    }
+    
+    // And add trailing implicit operands.
+    for (; CurIndex != NumMIOperands; ++CurIndex) {
+      std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands,
+                                                                 CurIndex);
+
+      if (!Tie) {
+        // If not, this is some implicit operand. Just assume it is a register
+        // for now.
+        CvtOS << "    Inst.addOperand(MCOperand::CreateReg(0));\n";
+      } else {
+        // Copy the tied operand.
+        assert(Tie->first>Tie->second && "Tied operand preceeds its target!");
+        CvtOS << "    Inst.addOperand(Inst.getOperand("
+              << Tie->second << "));\n";
+      }
+    }
+
+    CvtOS << "    return;\n";
+  }
+
+  // Finish the convert function.
+
+  CvtOS << "  }\n";
+  CvtOS << "}\n\n";
+
+  // Finish the enum, and drop the convert function after it.
+
+  OS << "  NumConversionVariants\n";
+  OS << "};\n\n";
+  
+  OS << CvtOS.str();
+}
+
+/// EmitMatchClassEnumeration - Emit the enumeration for match class kinds.
+static void EmitMatchClassEnumeration(CodeGenTarget &Target,
+                                      std::vector<ClassInfo*> &Infos,
+                                      raw_ostream &OS) {
+  OS << "namespace {\n\n";
+
+  OS << "/// MatchClassKind - The kinds of classes which participate in\n"
+     << "/// instruction matching.\n";
+  OS << "enum MatchClassKind {\n";
+  OS << "  InvalidMatchClass = 0,\n";
+  for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 
+         ie = Infos.end(); it != ie; ++it) {
+    ClassInfo &CI = **it;
+    OS << "  " << CI.Name << ", // ";
+    if (CI.Kind == ClassInfo::Token) {
+      OS << "'" << CI.ValueName << "'\n";
+    } else if (CI.isRegisterClass()) {
+      if (!CI.ValueName.empty())
+        OS << "register class '" << CI.ValueName << "'\n";
+      else
+        OS << "derived register class\n";
+    } else {
+      OS << "user defined class '" << CI.ValueName << "'\n";
+    }
+  }
+  OS << "  NumMatchClassKinds\n";
+  OS << "};\n\n";
+
+  OS << "}\n\n";
+}
+
+/// EmitClassifyOperand - Emit the function to classify an operand.
+static void EmitClassifyOperand(CodeGenTarget &Target,
+                                AsmMatcherInfo &Info,
+                                raw_ostream &OS) {
+  OS << "static MatchClassKind ClassifyOperand(MCParsedAsmOperand *GOp) {\n"
+     << "  " << Target.getName() << "Operand &Operand = *("
+     << Target.getName() << "Operand*)GOp;\n";
+
+  // Classify tokens.
+  OS << "  if (Operand.isToken())\n";
+  OS << "    return MatchTokenString(Operand.getToken());\n\n";
+
+  // Classify registers.
+  //
+  // FIXME: Don't hardcode isReg, getReg.
+  OS << "  if (Operand.isReg()) {\n";
+  OS << "    switch (Operand.getReg()) {\n";
+  OS << "    default: return InvalidMatchClass;\n";
+  for (std::map<Record*, ClassInfo*>::iterator 
+         it = Info.RegisterClasses.begin(), ie = Info.RegisterClasses.end();
+       it != ie; ++it)
+    OS << "    case " << Target.getName() << "::" 
+       << it->first->getName() << ": return " << it->second->Name << ";\n";
+  OS << "    }\n";
+  OS << "  }\n\n";
+
+  // Classify user defined operands.
+  for (std::vector<ClassInfo*>::iterator it = Info.Classes.begin(), 
+         ie = Info.Classes.end(); it != ie; ++it) {
+    ClassInfo &CI = **it;
+
+    if (!CI.isUserClass())
+      continue;
+
+    OS << "  // '" << CI.ClassName << "' class";
+    if (!CI.SuperClasses.empty()) {
+      OS << ", subclass of ";
+      for (unsigned i = 0, e = CI.SuperClasses.size(); i != e; ++i) {
+        if (i) OS << ", ";
+        OS << "'" << CI.SuperClasses[i]->ClassName << "'";
+        assert(CI < *CI.SuperClasses[i] && "Invalid class relation!");
+      }
+    }
+    OS << "\n";
+
+    OS << "  if (Operand." << CI.PredicateMethod << "()) {\n";
+      
+    // Validate subclass relationships.
+    if (!CI.SuperClasses.empty()) {
+      for (unsigned i = 0, e = CI.SuperClasses.size(); i != e; ++i)
+        OS << "    assert(Operand." << CI.SuperClasses[i]->PredicateMethod
+           << "() && \"Invalid class relationship!\");\n";
+    }
+
+    OS << "    return " << CI.Name << ";\n";
+    OS << "  }\n\n";
+  }
+  OS << "  return InvalidMatchClass;\n";
+  OS << "}\n\n";
+}
+
+/// EmitIsSubclass - Emit the subclass predicate function.
+static void EmitIsSubclass(CodeGenTarget &Target,
+                           std::vector<ClassInfo*> &Infos,
+                           raw_ostream &OS) {
+  OS << "/// IsSubclass - Compute whether \\arg A is a subclass of \\arg B.\n";
+  OS << "static bool IsSubclass(MatchClassKind A, MatchClassKind B) {\n";
+  OS << "  if (A == B)\n";
+  OS << "    return true;\n\n";
+
+  OS << "  switch (A) {\n";
+  OS << "  default:\n";
+  OS << "    return false;\n";
+  for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 
+         ie = Infos.end(); it != ie; ++it) {
+    ClassInfo &A = **it;
+
+    if (A.Kind != ClassInfo::Token) {
+      std::vector<StringRef> SuperClasses;
+      for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 
+             ie = Infos.end(); it != ie; ++it) {
+        ClassInfo &B = **it;
+
+        if (&A != &B && A.isSubsetOf(B))
+          SuperClasses.push_back(B.Name);
+      }
+
+      if (SuperClasses.empty())
+        continue;
+
+      OS << "\n  case " << A.Name << ":\n";
+
+      if (SuperClasses.size() == 1) {
+        OS << "    return B == " << SuperClasses.back() << ";\n";
+        continue;
+      }
+
+      OS << "    switch (B) {\n";
+      OS << "    default: return false;\n";
+      for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
+        OS << "    case " << SuperClasses[i] << ": return true;\n";
+      OS << "    }\n";
+    }
+  }
+  OS << "  }\n";
+  OS << "}\n\n";
+}
+
+typedef std::pair<std::string, std::string> StringPair;
+
+/// FindFirstNonCommonLetter - Find the first character in the keys of the
+/// string pairs that is not shared across the whole set of strings.  All
+/// strings are assumed to have the same length.
+static unsigned 
+FindFirstNonCommonLetter(const std::vector<const StringPair*> &Matches) {
+  assert(!Matches.empty());
+  for (unsigned i = 0, e = Matches[0]->first.size(); i != e; ++i) {
+    // Check to see if letter i is the same across the set.
+    char Letter = Matches[0]->first[i];
+    
+    for (unsigned str = 0, e = Matches.size(); str != e; ++str)
+      if (Matches[str]->first[i] != Letter)
+        return i;
+  }
+  
+  return Matches[0]->first.size();
+}
+
+/// EmitStringMatcherForChar - Given a set of strings that are known to be the
+/// same length and whose characters leading up to CharNo are the same, emit
+/// code to verify that CharNo and later are the same.
+///
+/// \return - True if control can leave the emitted code fragment.
+static bool EmitStringMatcherForChar(const std::string &StrVariableName,
+                                  const std::vector<const StringPair*> &Matches,
+                                     unsigned CharNo, unsigned IndentCount,
+                                     raw_ostream &OS) {
+  assert(!Matches.empty() && "Must have at least one string to match!");
+  std::string Indent(IndentCount*2+4, ' ');
+
+  // If we have verified that the entire string matches, we're done: output the
+  // matching code.
+  if (CharNo == Matches[0]->first.size()) {
+    assert(Matches.size() == 1 && "Had duplicate keys to match on");
+    
+    // FIXME: If Matches[0].first has embeded \n, this will be bad.
+    OS << Indent << Matches[0]->second << "\t // \"" << Matches[0]->first
+       << "\"\n";
+    return false;
+  }
+  
+  // Bucket the matches by the character we are comparing.
+  std::map<char, std::vector<const StringPair*> > MatchesByLetter;
+  
+  for (unsigned i = 0, e = Matches.size(); i != e; ++i)
+    MatchesByLetter[Matches[i]->first[CharNo]].push_back(Matches[i]);
+  
+
+  // If we have exactly one bucket to match, see how many characters are common
+  // across the whole set and match all of them at once.
+  if (MatchesByLetter.size() == 1) {
+    unsigned FirstNonCommonLetter = FindFirstNonCommonLetter(Matches);
+    unsigned NumChars = FirstNonCommonLetter-CharNo;
+    
+    // Emit code to break out if the prefix doesn't match.
+    if (NumChars == 1) {
+      // Do the comparison with if (Str[1] != 'f')
+      // FIXME: Need to escape general characters.
+      OS << Indent << "if (" << StrVariableName << "[" << CharNo << "] != '"
+         << Matches[0]->first[CharNo] << "')\n";
+      OS << Indent << "  break;\n";
+    } else {
+      // Do the comparison with if (Str.substr(1,3) != "foo").    
+      // FIXME: Need to escape general strings.
+      OS << Indent << "if (" << StrVariableName << ".substr(" << CharNo << ","
+         << NumChars << ") != \"";
+      OS << Matches[0]->first.substr(CharNo, NumChars) << "\")\n";
+      OS << Indent << "  break;\n";
+    }
+    
+    return EmitStringMatcherForChar(StrVariableName, Matches, 
+                                    FirstNonCommonLetter, IndentCount, OS);
+  }
+  
+  // Otherwise, we have multiple possible things, emit a switch on the
+  // character.
+  OS << Indent << "switch (" << StrVariableName << "[" << CharNo << "]) {\n";
+  OS << Indent << "default: break;\n";
+  
+  for (std::map<char, std::vector<const StringPair*> >::iterator LI = 
+       MatchesByLetter.begin(), E = MatchesByLetter.end(); LI != E; ++LI) {
+    // TODO: escape hard stuff (like \n) if we ever care about it.
+    OS << Indent << "case '" << LI->first << "':\t // "
+       << LI->second.size() << " strings to match.\n";
+    if (EmitStringMatcherForChar(StrVariableName, LI->second, CharNo+1,
+                                 IndentCount+1, OS))
+      OS << Indent << "  break;\n";
+  }
+  
+  OS << Indent << "}\n";
+  return true;
+}
+
+
+/// EmitStringMatcher - Given a list of strings and code to execute when they
+/// match, output a simple switch tree to classify the input string.
+/// 
+/// If a match is found, the code in Vals[i].second is executed; control must
+/// not exit this code fragment.  If nothing matches, execution falls through.
+///
+/// \param StrVariableName - The name of the variable to test.
+static void EmitStringMatcher(const std::string &StrVariableName,
+                              const std::vector<StringPair> &Matches,
+                              raw_ostream &OS) {
+  // First level categorization: group strings by length.
+  std::map<unsigned, std::vector<const StringPair*> > MatchesByLength;
+  
+  for (unsigned i = 0, e = Matches.size(); i != e; ++i)
+    MatchesByLength[Matches[i].first.size()].push_back(&Matches[i]);
+  
+  // Output a switch statement on length and categorize the elements within each
+  // bin.
+  OS << "  switch (" << StrVariableName << ".size()) {\n";
+  OS << "  default: break;\n";
+  
+  for (std::map<unsigned, std::vector<const StringPair*> >::iterator LI =
+       MatchesByLength.begin(), E = MatchesByLength.end(); LI != E; ++LI) {
+    OS << "  case " << LI->first << ":\t // " << LI->second.size()
+       << " strings to match.\n";
+    if (EmitStringMatcherForChar(StrVariableName, LI->second, 0, 0, OS))
+      OS << "    break;\n";
+  }
+  
+  OS << "  }\n";
+}
+
+
+/// EmitMatchTokenString - Emit the function to match a token string to the
+/// appropriate match class value.
+static void EmitMatchTokenString(CodeGenTarget &Target,
+                                 std::vector<ClassInfo*> &Infos,
+                                 raw_ostream &OS) {
+  // Construct the match list.
+  std::vector<StringPair> Matches;
+  for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 
+         ie = Infos.end(); it != ie; ++it) {
+    ClassInfo &CI = **it;
+
+    if (CI.Kind == ClassInfo::Token)
+      Matches.push_back(StringPair(CI.ValueName, "return " + CI.Name + ";"));
+  }
+
+  OS << "static MatchClassKind MatchTokenString(StringRef Name) {\n";
+
+  EmitStringMatcher("Name", Matches, OS);
+
+  OS << "  return InvalidMatchClass;\n";
+  OS << "}\n\n";
+}
+
+/// EmitMatchRegisterName - Emit the function to match a string to the target
+/// specific register enum.
+static void EmitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser,
+                                  raw_ostream &OS) {
+  // Construct the match list.
+  std::vector<StringPair> Matches;
+  for (unsigned i = 0, e = Target.getRegisters().size(); i != e; ++i) {
+    const CodeGenRegister &Reg = Target.getRegisters()[i];
+    if (Reg.TheDef->getValueAsString("AsmName").empty())
+      continue;
+
+    Matches.push_back(StringPair(Reg.TheDef->getValueAsString("AsmName"),
+                                 "return " + utostr(i + 1) + ";"));
+  }
+  
+  OS << "static unsigned MatchRegisterName(StringRef Name) {\n";
+
+  EmitStringMatcher("Name", Matches, OS);
+  
+  OS << "  return 0;\n";
+  OS << "}\n\n";
+}
+
+/// EmitSubtargetFeatureFlagEnumeration - Emit the subtarget feature flag
+/// definitions.
+static void EmitSubtargetFeatureFlagEnumeration(CodeGenTarget &Target,
+                                                AsmMatcherInfo &Info,
+                                                raw_ostream &OS) {
+  OS << "// Flags for subtarget features that participate in "
+     << "instruction matching.\n";
+  OS << "enum SubtargetFeatureFlag {\n";
+  for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator
+         it = Info.SubtargetFeatures.begin(),
+         ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
+    SubtargetFeatureInfo &SFI = *it->second;
+    OS << "  " << SFI.EnumName << " = (1 << " << SFI.Index << "),\n";
+  }
+  OS << "  Feature_None = 0\n";
+  OS << "};\n\n";
+}
+
+/// EmitComputeAvailableFeatures - Emit the function to compute the list of
+/// available features given a subtarget.
+static void EmitComputeAvailableFeatures(CodeGenTarget &Target,
+                                         AsmMatcherInfo &Info,
+                                         raw_ostream &OS) {
+  std::string ClassName =
+    Info.AsmParser->getValueAsString("AsmParserClassName");
+
+  OS << "unsigned " << Target.getName() << ClassName << "::\n"
+     << "ComputeAvailableFeatures(const " << Target.getName()
+     << "Subtarget *Subtarget) const {\n";
+  OS << "  unsigned Features = 0;\n";
+  for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator
+         it = Info.SubtargetFeatures.begin(),
+         ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
+    SubtargetFeatureInfo &SFI = *it->second;
+    OS << "  if (" << SFI.TheDef->getValueAsString("CondString")
+       << ")\n";
+    OS << "    Features |= " << SFI.EnumName << ";\n";
+  }
+  OS << "  return Features;\n";
+  OS << "}\n\n";
+}
+
+void AsmMatcherEmitter::run(raw_ostream &OS) {
+  CodeGenTarget Target;
+  Record *AsmParser = Target.getAsmParser();
+  std::string ClassName = AsmParser->getValueAsString("AsmParserClassName");
+
+  // Compute the information on the instructions to match.
+  AsmMatcherInfo Info(AsmParser);
+  Info.BuildInfo(Target);
+
+  // Sort the instruction table using the partial order on classes. We use
+  // stable_sort to ensure that ambiguous instructions are still
+  // deterministically ordered.
+  std::stable_sort(Info.Instructions.begin(), Info.Instructions.end(),
+                   less_ptr<InstructionInfo>());
+  
+  DEBUG_WITH_TYPE("instruction_info", {
+      for (std::vector<InstructionInfo*>::iterator 
+             it = Info.Instructions.begin(), ie = Info.Instructions.end(); 
+           it != ie; ++it)
+        (*it)->dump();
+    });
+
+  // Check for ambiguous instructions.
+  unsigned NumAmbiguous = 0;
+  for (unsigned i = 0, e = Info.Instructions.size(); i != e; ++i) {
+    for (unsigned j = i + 1; j != e; ++j) {
+      InstructionInfo &A = *Info.Instructions[i];
+      InstructionInfo &B = *Info.Instructions[j];
+    
+      if (A.CouldMatchAmiguouslyWith(B)) {
+        DEBUG_WITH_TYPE("ambiguous_instrs", {
+            errs() << "warning: ambiguous instruction match:\n";
+            A.dump();
+            errs() << "\nis incomparable with:\n";
+            B.dump();
+            errs() << "\n\n";
+          });
+        ++NumAmbiguous;
+      }
+    }
+  }
+  if (NumAmbiguous)
+    DEBUG_WITH_TYPE("ambiguous_instrs", {
+        errs() << "warning: " << NumAmbiguous 
+               << " ambiguous instructions!\n";
+      });
+
+  // Write the output.
+
+  EmitSourceFileHeader("Assembly Matcher Source Fragment", OS);
+
+  // Emit the subtarget feature enumeration.
+  EmitSubtargetFeatureFlagEnumeration(Target, Info, OS);
+
+  // Emit the function to match a register name to number.
+  EmitMatchRegisterName(Target, AsmParser, OS);
+  
+  OS << "#ifndef REGISTERS_ONLY\n\n";
+
+  // Generate the unified function to convert operands into an MCInst.
+  EmitConvertToMCInst(Target, Info.Instructions, OS);
+
+  // Emit the enumeration for classes which participate in matching.
+  EmitMatchClassEnumeration(Target, Info.Classes, OS);
+
+  // Emit the routine to match token strings to their match class.
+  EmitMatchTokenString(Target, Info.Classes, OS);
+
+  // Emit the routine to classify an operand.
+  EmitClassifyOperand(Target, Info, OS);
+
+  // Emit the subclass predicate routine.
+  EmitIsSubclass(Target, Info.Classes, OS);
+
+  // Emit the available features compute function.
+  EmitComputeAvailableFeatures(Target, Info, OS);
+
+  // Finally, build the match function.
+
+  size_t MaxNumOperands = 0;
+  for (std::vector<InstructionInfo*>::const_iterator it =
+         Info.Instructions.begin(), ie = Info.Instructions.end();
+       it != ie; ++it)
+    MaxNumOperands = std::max(MaxNumOperands, (*it)->Operands.size());
+
+  const std::string &MatchName =
+    AsmParser->getValueAsString("MatchInstructionName");
+  OS << "bool " << Target.getName() << ClassName << "::\n"
+     << MatchName
+     << "(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n";
+  OS.indent(MatchName.size() + 1);
+  OS << "MCInst &Inst) {\n";
+
+  // Emit the static match table; unused classes get initalized to 0 which is
+  // guaranteed to be InvalidMatchClass.
+  //
+  // FIXME: We can reduce the size of this table very easily. First, we change
+  // it so that store the kinds in separate bit-fields for each index, which
+  // only needs to be the max width used for classes at that index (we also need
+  // to reject based on this during classification). If we then make sure to
+  // order the match kinds appropriately (putting mnemonics last), then we
+  // should only end up using a few bits for each class, especially the ones
+  // following the mnemonic.
+  OS << "  static const struct MatchEntry {\n";
+  OS << "    unsigned Opcode;\n";
+  OS << "    ConversionKind ConvertFn;\n";
+  OS << "    MatchClassKind Classes[" << MaxNumOperands << "];\n";
+  OS << "    unsigned RequiredFeatures;\n";
+  OS << "  } MatchTable[" << Info.Instructions.size() << "] = {\n";
+
+  for (std::vector<InstructionInfo*>::const_iterator it =
+         Info.Instructions.begin(), ie = Info.Instructions.end();
+       it != ie; ++it) {
+    InstructionInfo &II = **it;
+
+    OS << "    { " << Target.getName() << "::" << II.InstrName
+       << ", " << II.ConversionFnKind << ", { ";
+    for (unsigned i = 0, e = II.Operands.size(); i != e; ++i) {
+      InstructionInfo::Operand &Op = II.Operands[i];
+      
+      if (i) OS << ", ";
+      OS << Op.Class->Name;
+    }
+    OS << " }, ";
+
+    // Write the required features mask.
+    if (!II.RequiredFeatures.empty()) {
+      for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) {
+        if (i) OS << "|";
+        OS << II.RequiredFeatures[i]->EnumName;
+      }
+    } else
+      OS << "0";
+
+    OS << "},\n";
+  }
+
+  OS << "  };\n\n";
+
+
+  // Emit code to get the available features.
+  OS << "  // Get the current feature set.\n";
+  OS << "  unsigned AvailableFeatures = getAvailableFeatures();\n\n";
+
+  // Emit code to compute the class list for this operand vector.
+  OS << "  // Eliminate obvious mismatches.\n";
+  OS << "  if (Operands.size() > " << MaxNumOperands << ")\n";
+  OS << "    return true;\n\n";
+
+  OS << "  // Compute the class list for this operand vector.\n";
+  OS << "  MatchClassKind Classes[" << MaxNumOperands << "];\n";
+  OS << "  for (unsigned i = 0, e = Operands.size(); i != e; ++i) {\n";
+  OS << "    Classes[i] = ClassifyOperand(Operands[i]);\n\n";
+
+  OS << "    // Check for invalid operands before matching.\n";
+  OS << "    if (Classes[i] == InvalidMatchClass)\n";
+  OS << "      return true;\n";
+  OS << "  }\n\n";
+
+  OS << "  // Mark unused classes.\n";
+  OS << "  for (unsigned i = Operands.size(), e = " << MaxNumOperands << "; "
+     << "i != e; ++i)\n";
+  OS << "    Classes[i] = InvalidMatchClass;\n\n";
+
+  // Emit code to search the table.
+  OS << "  // Search the table.\n";
+  OS << "  for (const MatchEntry *it = MatchTable, "
+     << "*ie = MatchTable + " << Info.Instructions.size()
+     << "; it != ie; ++it) {\n";
+
+  // Emit check that the required features are available.
+    OS << "    if ((AvailableFeatures & it->RequiredFeatures) "
+       << "!= it->RequiredFeatures)\n";
+    OS << "      continue;\n";
+
+  // Emit check that the subclasses match.
+  for (unsigned i = 0; i != MaxNumOperands; ++i) {
+    OS << "    if (!IsSubclass(Classes[" 
+       << i << "], it->Classes[" << i << "]))\n";
+    OS << "      continue;\n";
+  }
+  OS << "\n";
+  OS << "    ConvertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);\n";
+
+  // Call the post-processing function, if used.
+  std::string InsnCleanupFn =
+    AsmParser->getValueAsString("AsmParserInstCleanup");
+  if (!InsnCleanupFn.empty())
+    OS << "    " << InsnCleanupFn << "(Inst);\n";
+
+  OS << "    return false;\n";
+  OS << "  }\n\n";
+
+  OS << "  return true;\n";
+  OS << "}\n\n";
+  
+  OS << "#endif // REGISTERS_ONLY\n";
+}
diff --git a/src/LLVM/utils/TableGen/AsmMatcherEmitter.h b/src/LLVM/utils/TableGen/AsmMatcherEmitter.h
new file mode 100644
index 0000000..729c938
--- /dev/null
+++ b/src/LLVM/utils/TableGen/AsmMatcherEmitter.h
@@ -0,0 +1,33 @@
+//===- AsmMatcherEmitter.h - Generate an assembly matcher -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend emits a target specifier matcher for converting parsed
+// assembly operands in the MCInst structures.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ASMMATCHER_EMITTER_H
+#define ASMMATCHER_EMITTER_H
+
+#include "TableGenBackend.h"
+#include <map>
+#include <vector>
+#include <cassert>
+
+namespace llvm {
+  class AsmMatcherEmitter : public TableGenBackend {
+    RecordKeeper &Records;
+  public:
+    AsmMatcherEmitter(RecordKeeper &R) : Records(R) {}
+
+    // run - Output the matcher, returning true on failure.
+    void run(raw_ostream &o);
+  };
+}
+#endif
diff --git a/src/LLVM/utils/TableGen/AsmWriterEmitter.cpp b/src/LLVM/utils/TableGen/AsmWriterEmitter.cpp
new file mode 100644
index 0000000..23f13c2
--- /dev/null
+++ b/src/LLVM/utils/TableGen/AsmWriterEmitter.cpp
@@ -0,0 +1,548 @@
+//===- AsmWriterEmitter.cpp - Generate an assembly writer -----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend is emits an assembly printer for the current target.
+// Note that this is currently fairly skeletal, but will grow over time.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AsmWriterEmitter.h"
+#include "AsmWriterInst.h"
+#include "CodeGenTarget.h"
+#include "Record.h"
+#include "StringToOffsetTable.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include <algorithm>
+using namespace llvm;
+
+static void PrintCases(std::vector<std::pair<std::string,
+                       AsmWriterOperand> > &OpsToPrint, raw_ostream &O) {
+  O << "    case " << OpsToPrint.back().first << ": ";
+  AsmWriterOperand TheOp = OpsToPrint.back().second;
+  OpsToPrint.pop_back();
+
+  // Check to see if any other operands are identical in this list, and if so,
+  // emit a case label for them.
+  for (unsigned i = OpsToPrint.size(); i != 0; --i)
+    if (OpsToPrint[i-1].second == TheOp) {
+      O << "\n    case " << OpsToPrint[i-1].first << ": ";
+      OpsToPrint.erase(OpsToPrint.begin()+i-1);
+    }
+
+  // Finally, emit the code.
+  O << TheOp.getCode();
+  O << "break;\n";
+}
+
+
+/// EmitInstructions - Emit the last instruction in the vector and any other
+/// instructions that are suitably similar to it.
+static void EmitInstructions(std::vector<AsmWriterInst> &Insts,
+                             raw_ostream &O) {
+  AsmWriterInst FirstInst = Insts.back();
+  Insts.pop_back();
+
+  std::vector<AsmWriterInst> SimilarInsts;
+  unsigned DifferingOperand = ~0;
+  for (unsigned i = Insts.size(); i != 0; --i) {
+    unsigned DiffOp = Insts[i-1].MatchesAllButOneOp(FirstInst);
+    if (DiffOp != ~1U) {
+      if (DifferingOperand == ~0U)  // First match!
+        DifferingOperand = DiffOp;
+
+      // If this differs in the same operand as the rest of the instructions in
+      // this class, move it to the SimilarInsts list.
+      if (DifferingOperand == DiffOp || DiffOp == ~0U) {
+        SimilarInsts.push_back(Insts[i-1]);
+        Insts.erase(Insts.begin()+i-1);
+      }
+    }
+  }
+
+  O << "  case " << FirstInst.CGI->Namespace << "::"
+    << FirstInst.CGI->TheDef->getName() << ":\n";
+  for (unsigned i = 0, e = SimilarInsts.size(); i != e; ++i)
+    O << "  case " << SimilarInsts[i].CGI->Namespace << "::"
+      << SimilarInsts[i].CGI->TheDef->getName() << ":\n";
+  for (unsigned i = 0, e = FirstInst.Operands.size(); i != e; ++i) {
+    if (i != DifferingOperand) {
+      // If the operand is the same for all instructions, just print it.
+      O << "    " << FirstInst.Operands[i].getCode();
+    } else {
+      // If this is the operand that varies between all of the instructions,
+      // emit a switch for just this operand now.
+      O << "    switch (MI->getOpcode()) {\n";
+      std::vector<std::pair<std::string, AsmWriterOperand> > OpsToPrint;
+      OpsToPrint.push_back(std::make_pair(FirstInst.CGI->Namespace + "::" +
+                                          FirstInst.CGI->TheDef->getName(),
+                                          FirstInst.Operands[i]));
+
+      for (unsigned si = 0, e = SimilarInsts.size(); si != e; ++si) {
+        AsmWriterInst &AWI = SimilarInsts[si];
+        OpsToPrint.push_back(std::make_pair(AWI.CGI->Namespace+"::"+
+                                            AWI.CGI->TheDef->getName(),
+                                            AWI.Operands[i]));
+      }
+      std::reverse(OpsToPrint.begin(), OpsToPrint.end());
+      while (!OpsToPrint.empty())
+        PrintCases(OpsToPrint, O);
+      O << "    }";
+    }
+    O << "\n";
+  }
+  O << "    break;\n";
+}
+
+void AsmWriterEmitter::
+FindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands, 
+                          std::vector<unsigned> &InstIdxs,
+                          std::vector<unsigned> &InstOpsUsed) const {
+  InstIdxs.assign(NumberedInstructions.size(), ~0U);
+  
+  // This vector parallels UniqueOperandCommands, keeping track of which
+  // instructions each case are used for.  It is a comma separated string of
+  // enums.
+  std::vector<std::string> InstrsForCase;
+  InstrsForCase.resize(UniqueOperandCommands.size());
+  InstOpsUsed.assign(UniqueOperandCommands.size(), 0);
+  
+  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
+    const AsmWriterInst *Inst = getAsmWriterInstByID(i);
+    if (Inst == 0) continue;  // PHI, INLINEASM, PROLOG_LABEL, etc.
+    
+    std::string Command;
+    if (Inst->Operands.empty())
+      continue;   // Instruction already done.
+
+    Command = "    " + Inst->Operands[0].getCode() + "\n";
+
+    // Check to see if we already have 'Command' in UniqueOperandCommands.
+    // If not, add it.
+    bool FoundIt = false;
+    for (unsigned idx = 0, e = UniqueOperandCommands.size(); idx != e; ++idx)
+      if (UniqueOperandCommands[idx] == Command) {
+        InstIdxs[i] = idx;
+        InstrsForCase[idx] += ", ";
+        InstrsForCase[idx] += Inst->CGI->TheDef->getName();
+        FoundIt = true;
+        break;
+      }
+    if (!FoundIt) {
+      InstIdxs[i] = UniqueOperandCommands.size();
+      UniqueOperandCommands.push_back(Command);
+      InstrsForCase.push_back(Inst->CGI->TheDef->getName());
+
+      // This command matches one operand so far.
+      InstOpsUsed.push_back(1);
+    }
+  }
+  
+  // For each entry of UniqueOperandCommands, there is a set of instructions
+  // that uses it.  If the next command of all instructions in the set are
+  // identical, fold it into the command.
+  for (unsigned CommandIdx = 0, e = UniqueOperandCommands.size();
+       CommandIdx != e; ++CommandIdx) {
+    
+    for (unsigned Op = 1; ; ++Op) {
+      // Scan for the first instruction in the set.
+      std::vector<unsigned>::iterator NIT =
+        std::find(InstIdxs.begin(), InstIdxs.end(), CommandIdx);
+      if (NIT == InstIdxs.end()) break;  // No commonality.
+
+      // If this instruction has no more operands, we isn't anything to merge
+      // into this command.
+      const AsmWriterInst *FirstInst = 
+        getAsmWriterInstByID(NIT-InstIdxs.begin());
+      if (!FirstInst || FirstInst->Operands.size() == Op)
+        break;
+
+      // Otherwise, scan to see if all of the other instructions in this command
+      // set share the operand.
+      bool AllSame = true;
+      // Keep track of the maximum, number of operands or any
+      // instruction we see in the group.
+      size_t MaxSize = FirstInst->Operands.size();
+
+      for (NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx);
+           NIT != InstIdxs.end();
+           NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx)) {
+        // Okay, found another instruction in this command set.  If the operand
+        // matches, we're ok, otherwise bail out.
+        const AsmWriterInst *OtherInst = 
+          getAsmWriterInstByID(NIT-InstIdxs.begin());
+
+        if (OtherInst &&
+            OtherInst->Operands.size() > FirstInst->Operands.size())
+          MaxSize = std::max(MaxSize, OtherInst->Operands.size());
+
+        if (!OtherInst || OtherInst->Operands.size() == Op ||
+            OtherInst->Operands[Op] != FirstInst->Operands[Op]) {
+          AllSame = false;
+          break;
+        }
+      }
+      if (!AllSame) break;
+      
+      // Okay, everything in this command set has the same next operand.  Add it
+      // to UniqueOperandCommands and remember that it was consumed.
+      std::string Command = "    " + FirstInst->Operands[Op].getCode() + "\n";
+      
+      UniqueOperandCommands[CommandIdx] += Command;
+      InstOpsUsed[CommandIdx]++;
+    }
+  }
+  
+  // Prepend some of the instructions each case is used for onto the case val.
+  for (unsigned i = 0, e = InstrsForCase.size(); i != e; ++i) {
+    std::string Instrs = InstrsForCase[i];
+    if (Instrs.size() > 70) {
+      Instrs.erase(Instrs.begin()+70, Instrs.end());
+      Instrs += "...";
+    }
+    
+    if (!Instrs.empty())
+      UniqueOperandCommands[i] = "    // " + Instrs + "\n" + 
+        UniqueOperandCommands[i];
+  }
+}
+
+
+static void UnescapeString(std::string &Str) {
+  for (unsigned i = 0; i != Str.size(); ++i) {
+    if (Str[i] == '\\' && i != Str.size()-1) {
+      switch (Str[i+1]) {
+      default: continue;  // Don't execute the code after the switch.
+      case 'a': Str[i] = '\a'; break;
+      case 'b': Str[i] = '\b'; break;
+      case 'e': Str[i] = 27; break;
+      case 'f': Str[i] = '\f'; break;
+      case 'n': Str[i] = '\n'; break;
+      case 'r': Str[i] = '\r'; break;
+      case 't': Str[i] = '\t'; break;
+      case 'v': Str[i] = '\v'; break;
+      case '"': Str[i] = '\"'; break;
+      case '\'': Str[i] = '\''; break;
+      case '\\': Str[i] = '\\'; break;
+      }
+      // Nuke the second character.
+      Str.erase(Str.begin()+i+1);
+    }
+  }
+}
+
+/// EmitPrintInstruction - Generate the code for the "printInstruction" method
+/// implementation.
+void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
+  CodeGenTarget Target;
+  Record *AsmWriter = Target.getAsmWriter();
+  std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
+  
+  O <<
+  "/// printInstruction - This method is automatically generated by tablegen\n"
+  "/// from the instruction set description.\n"
+    "void " << Target.getName() << ClassName
+            << "::printInstruction(const MachineInstr *MI, raw_ostream &O) {\n";
+
+  std::vector<AsmWriterInst> Instructions;
+
+  for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
+         E = Target.inst_end(); I != E; ++I)
+    if (!(*I)->AsmString.empty() &&
+        (*I)->TheDef->getName() != "PHI")
+      Instructions.push_back(
+        AsmWriterInst(**I, 
+                      AsmWriter->getValueAsInt("Variant"),
+                      AsmWriter->getValueAsInt("FirstOperandColumn"),
+                      AsmWriter->getValueAsInt("OperandSpacing")));
+
+  // Get the instruction numbering.
+  NumberedInstructions = Target.getInstructionsByEnumValue();
+  
+  // Compute the CodeGenInstruction -> AsmWriterInst mapping.  Note that not
+  // all machine instructions are necessarily being printed, so there may be
+  // target instructions not in this map.
+  for (unsigned i = 0, e = Instructions.size(); i != e; ++i)
+    CGIAWIMap.insert(std::make_pair(Instructions[i].CGI, &Instructions[i]));
+
+  // Build an aggregate string, and build a table of offsets into it.
+  StringToOffsetTable StringTable;
+  
+  /// OpcodeInfo - This encodes the index of the string to use for the first
+  /// chunk of the output as well as indices used for operand printing.
+  std::vector<unsigned> OpcodeInfo;
+  
+  unsigned MaxStringIdx = 0;
+  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
+    AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions[i]];
+    unsigned Idx;
+    if (AWI == 0) {
+      // Something not handled by the asmwriter printer.
+      Idx = ~0U;
+    } else if (AWI->Operands[0].OperandType != 
+                        AsmWriterOperand::isLiteralTextOperand ||
+               AWI->Operands[0].Str.empty()) {
+      // Something handled by the asmwriter printer, but with no leading string.
+      Idx = StringTable.GetOrAddStringOffset("");
+    } else {
+      std::string Str = AWI->Operands[0].Str;
+      UnescapeString(Str);
+      Idx = StringTable.GetOrAddStringOffset(Str);
+      MaxStringIdx = std::max(MaxStringIdx, Idx);
+      
+      // Nuke the string from the operand list.  It is now handled!
+      AWI->Operands.erase(AWI->Operands.begin());
+    }
+    
+    // Bias offset by one since we want 0 as a sentinel.
+    OpcodeInfo.push_back(Idx+1);
+  }
+  
+  // Figure out how many bits we used for the string index.
+  unsigned AsmStrBits = Log2_32_Ceil(MaxStringIdx+2);
+  
+  // To reduce code size, we compactify common instructions into a few bits
+  // in the opcode-indexed table.
+  unsigned BitsLeft = 32-AsmStrBits;
+
+  std::vector<std::vector<std::string> > TableDrivenOperandPrinters;
+  
+  while (1) {
+    std::vector<std::string> UniqueOperandCommands;
+    std::vector<unsigned> InstIdxs;
+    std::vector<unsigned> NumInstOpsHandled;
+    FindUniqueOperandCommands(UniqueOperandCommands, InstIdxs,
+                              NumInstOpsHandled);
+    
+    // If we ran out of operands to print, we're done.
+    if (UniqueOperandCommands.empty()) break;
+    
+    // Compute the number of bits we need to represent these cases, this is
+    // ceil(log2(numentries)).
+    unsigned NumBits = Log2_32_Ceil(UniqueOperandCommands.size());
+    
+    // If we don't have enough bits for this operand, don't include it.
+    if (NumBits > BitsLeft) {
+      DEBUG(errs() << "Not enough bits to densely encode " << NumBits
+                   << " more bits\n");
+      break;
+    }
+    
+    // Otherwise, we can include this in the initial lookup table.  Add it in.
+    BitsLeft -= NumBits;
+    for (unsigned i = 0, e = InstIdxs.size(); i != e; ++i)
+      if (InstIdxs[i] != ~0U)
+        OpcodeInfo[i] |= InstIdxs[i] << (BitsLeft+AsmStrBits);
+    
+    // Remove the info about this operand.
+    for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
+      if (AsmWriterInst *Inst = getAsmWriterInstByID(i))
+        if (!Inst->Operands.empty()) {
+          unsigned NumOps = NumInstOpsHandled[InstIdxs[i]];
+          assert(NumOps <= Inst->Operands.size() &&
+                 "Can't remove this many ops!");
+          Inst->Operands.erase(Inst->Operands.begin(),
+                               Inst->Operands.begin()+NumOps);
+        }
+    }
+    
+    // Remember the handlers for this set of operands.
+    TableDrivenOperandPrinters.push_back(UniqueOperandCommands);
+  }
+  
+  
+  
+  O<<"  static const unsigned OpInfo[] = {\n";
+  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
+    O << "    " << OpcodeInfo[i] << "U,\t// "
+      << NumberedInstructions[i]->TheDef->getName() << "\n";
+  }
+  // Add a dummy entry so the array init doesn't end with a comma.
+  O << "    0U\n";
+  O << "  };\n\n";
+  
+  // Emit the string itself.
+  O << "  const char *AsmStrs = \n";
+  StringTable.EmitString(O);
+  O << ";\n\n";
+
+  O << "  O << \"\\t\";\n\n";
+
+  O << "  // Emit the opcode for the instruction.\n"
+    << "  unsigned Bits = OpInfo[MI->getOpcode()];\n"
+    << "  assert(Bits != 0 && \"Cannot print this instruction.\");\n"
+    << "  O << AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1;\n\n";
+
+  // Output the table driven operand information.
+  BitsLeft = 32-AsmStrBits;
+  for (unsigned i = 0, e = TableDrivenOperandPrinters.size(); i != e; ++i) {
+    std::vector<std::string> &Commands = TableDrivenOperandPrinters[i];
+
+    // Compute the number of bits we need to represent these cases, this is
+    // ceil(log2(numentries)).
+    unsigned NumBits = Log2_32_Ceil(Commands.size());
+    assert(NumBits <= BitsLeft && "consistency error");
+    
+    // Emit code to extract this field from Bits.
+    BitsLeft -= NumBits;
+    
+    O << "\n  // Fragment " << i << " encoded into " << NumBits
+      << " bits for " << Commands.size() << " unique commands.\n";
+    
+    if (Commands.size() == 2) {
+      // Emit two possibilitys with if/else.
+      O << "  if ((Bits >> " << (BitsLeft+AsmStrBits) << ") & "
+        << ((1 << NumBits)-1) << ") {\n"
+        << Commands[1]
+        << "  } else {\n"
+        << Commands[0]
+        << "  }\n\n";
+    } else {
+      O << "  switch ((Bits >> " << (BitsLeft+AsmStrBits) << ") & "
+        << ((1 << NumBits)-1) << ") {\n"
+        << "  default:   // unreachable.\n";
+      
+      // Print out all the cases.
+      for (unsigned i = 0, e = Commands.size(); i != e; ++i) {
+        O << "  case " << i << ":\n";
+        O << Commands[i];
+        O << "    break;\n";
+      }
+      O << "  }\n\n";
+    }
+  }
+  
+  // Okay, delete instructions with no operand info left.
+  for (unsigned i = 0, e = Instructions.size(); i != e; ++i) {
+    // Entire instruction has been emitted?
+    AsmWriterInst &Inst = Instructions[i];
+    if (Inst.Operands.empty()) {
+      Instructions.erase(Instructions.begin()+i);
+      --i; --e;
+    }
+  }
+
+    
+  // Because this is a vector, we want to emit from the end.  Reverse all of the
+  // elements in the vector.
+  std::reverse(Instructions.begin(), Instructions.end());
+  
+  
+  // Now that we've emitted all of the operand info that fit into 32 bits, emit
+  // information for those instructions that are left.  This is a less dense
+  // encoding, but we expect the main 32-bit table to handle the majority of
+  // instructions.
+  if (!Instructions.empty()) {
+    // Find the opcode # of inline asm.
+    O << "  switch (MI->getOpcode()) {\n";
+    while (!Instructions.empty())
+      EmitInstructions(Instructions, O);
+
+    O << "  }\n";
+    O << "  return;\n";
+  }
+
+  O << "}\n";
+}
+
+
+void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
+  CodeGenTarget Target;
+  Record *AsmWriter = Target.getAsmWriter();
+  std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
+  const std::vector<CodeGenRegister> &Registers = Target.getRegisters();
+  
+  StringToOffsetTable StringTable;
+  O <<
+  "\n\n/// getRegisterName - This method is automatically generated by tblgen\n"
+  "/// from the register set description.  This returns the assembler name\n"
+  "/// for the specified register.\n"
+  "const char *" << Target.getName() << ClassName
+  << "::getRegisterName(unsigned RegNo) {\n"
+  << "  assert(RegNo && RegNo < " << (Registers.size()+1)
+  << " && \"Invalid register number!\");\n"
+  << "\n"
+  << "  static const unsigned RegAsmOffset[] = {";
+  for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
+    const CodeGenRegister &Reg = Registers[i];
+
+    std::string AsmName = Reg.TheDef->getValueAsString("AsmName");
+    if (AsmName.empty())
+      AsmName = Reg.getName();
+    
+    
+    if ((i % 14) == 0)
+      O << "\n    ";
+    
+    O << StringTable.GetOrAddStringOffset(AsmName) << ", ";
+  }
+  O << "0\n"
+    << "  };\n"
+    << "\n";
+  
+  O << "  const char *AsmStrs =\n";
+  StringTable.EmitString(O);
+  O << ";\n";
+  
+  O << "  return AsmStrs+RegAsmOffset[RegNo-1];\n"
+    << "}\n";
+}
+
+void AsmWriterEmitter::EmitGetInstructionName(raw_ostream &O) {
+  CodeGenTarget Target;
+  Record *AsmWriter = Target.getAsmWriter();
+  std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
+
+  const std::vector<const CodeGenInstruction*> &NumberedInstructions =
+    Target.getInstructionsByEnumValue();
+  
+  StringToOffsetTable StringTable;
+  O <<
+"\n\n#ifdef GET_INSTRUCTION_NAME\n"
+"#undef GET_INSTRUCTION_NAME\n\n"
+"/// getInstructionName: This method is automatically generated by tblgen\n"
+"/// from the instruction set description.  This returns the enum name of the\n"
+"/// specified instruction.\n"
+  "const char *" << Target.getName() << ClassName
+  << "::getInstructionName(unsigned Opcode) {\n"
+  << "  assert(Opcode < " << NumberedInstructions.size()
+  << " && \"Invalid instruction number!\");\n"
+  << "\n"
+  << "  static const unsigned InstAsmOffset[] = {";
+  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
+    const CodeGenInstruction &Inst = *NumberedInstructions[i];
+    
+    std::string AsmName = Inst.TheDef->getName();
+    if ((i % 14) == 0)
+      O << "\n    ";
+    
+    O << StringTable.GetOrAddStringOffset(AsmName) << ", ";
+  }
+  O << "0\n"
+  << "  };\n"
+  << "\n";
+  
+  O << "  const char *Strs =\n";
+  StringTable.EmitString(O);
+  O << ";\n";
+  
+  O << "  return Strs+InstAsmOffset[Opcode];\n"
+  << "}\n\n#endif\n";
+}
+
+
+
+void AsmWriterEmitter::run(raw_ostream &O) {
+  EmitSourceFileHeader("Assembly Writer Source Fragment", O);
+  
+  EmitPrintInstruction(O);
+  EmitGetRegisterName(O);
+  EmitGetInstructionName(O);
+}
+
diff --git a/src/LLVM/utils/TableGen/AsmWriterEmitter.h b/src/LLVM/utils/TableGen/AsmWriterEmitter.h
new file mode 100644
index 0000000..9f7d776
--- /dev/null
+++ b/src/LLVM/utils/TableGen/AsmWriterEmitter.h
@@ -0,0 +1,54 @@
+//===- AsmWriterEmitter.h - Generate an assembly writer ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend is responsible for emitting an assembly printer for the
+// code generator.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ASMWRITER_EMITTER_H
+#define ASMWRITER_EMITTER_H
+
+#include "TableGenBackend.h"
+#include <map>
+#include <vector>
+#include <cassert>
+
+namespace llvm {
+  class AsmWriterInst;
+  class CodeGenInstruction;
+  
+  class AsmWriterEmitter : public TableGenBackend {
+    RecordKeeper &Records;
+    std::map<const CodeGenInstruction*, AsmWriterInst*> CGIAWIMap;
+    std::vector<const CodeGenInstruction*> NumberedInstructions;
+  public:
+    AsmWriterEmitter(RecordKeeper &R) : Records(R) {}
+
+    // run - Output the asmwriter, returning true on failure.
+    void run(raw_ostream &o);
+
+private:
+    void EmitPrintInstruction(raw_ostream &o);
+    void EmitGetRegisterName(raw_ostream &o);
+    void EmitGetInstructionName(raw_ostream &o);
+    
+    AsmWriterInst *getAsmWriterInstByID(unsigned ID) const {
+      assert(ID < NumberedInstructions.size());
+      std::map<const CodeGenInstruction*, AsmWriterInst*>::const_iterator I =
+        CGIAWIMap.find(NumberedInstructions[ID]);
+      assert(I != CGIAWIMap.end() && "Didn't find inst!");
+      return I->second;
+    }
+    void FindUniqueOperandCommands(std::vector<std::string> &UOC,
+                                   std::vector<unsigned> &InstIdxs,
+                                   std::vector<unsigned> &InstOpsUsed) const;
+  };
+}
+#endif
diff --git a/src/LLVM/utils/TableGen/AsmWriterInst.cpp b/src/LLVM/utils/TableGen/AsmWriterInst.cpp
new file mode 100644
index 0000000..b2228b0
--- /dev/null
+++ b/src/LLVM/utils/TableGen/AsmWriterInst.cpp
@@ -0,0 +1,265 @@
+//===- AsmWriterInst.h - Classes encapsulating a printable inst -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These classes implement a parser for assembly strings.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AsmWriterInst.h"
+#include "CodeGenTarget.h"
+#include "Record.h"
+#include "llvm/ADT/StringExtras.h"
+
+using namespace llvm;
+
+static bool isIdentChar(char C) {
+  return (C >= 'a' && C <= 'z') ||
+  (C >= 'A' && C <= 'Z') ||
+  (C >= '0' && C <= '9') ||
+  C == '_';
+}
+
+std::string AsmWriterOperand::getCode() const {
+  if (OperandType == isLiteralTextOperand) {
+    if (Str.size() == 1)
+      return "O << '" + Str + "'; ";
+    return "O << \"" + Str + "\"; ";
+  }
+  
+  if (OperandType == isLiteralStatementOperand)
+    return Str;
+  
+  std::string Result = Str + "(MI";
+  if (MIOpNo != ~0U)
+    Result += ", " + utostr(MIOpNo);
+  Result += ", O";
+  if (!MiModifier.empty())
+    Result += ", \"" + MiModifier + '"';
+  return Result + "); ";
+}
+
+/// ParseAsmString - Parse the specified Instruction's AsmString into this
+/// AsmWriterInst.
+///
+AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI,
+                             unsigned Variant,
+                             int FirstOperandColumn,
+                             int OperandSpacing) {
+  this->CGI = &CGI;
+  
+  unsigned CurVariant = ~0U;  // ~0 if we are outside a {.|.|.} region, other #.
+  
+  // This is the number of tabs we've seen if we're doing columnar layout.
+  unsigned CurColumn = 0;
+  
+  
+  // NOTE: Any extensions to this code need to be mirrored in the 
+  // AsmPrinter::printInlineAsm code that executes as compile time (assuming
+  // that inline asm strings should also get the new feature)!
+  const std::string &AsmString = CGI.AsmString;
+  std::string::size_type LastEmitted = 0;
+  while (LastEmitted != AsmString.size()) {
+    std::string::size_type DollarPos =
+    AsmString.find_first_of("${|}\\", LastEmitted);
+    if (DollarPos == std::string::npos) DollarPos = AsmString.size();
+    
+    // Emit a constant string fragment.
+    
+    if (DollarPos != LastEmitted) {
+      if (CurVariant == Variant || CurVariant == ~0U) {
+        for (; LastEmitted != DollarPos; ++LastEmitted)
+          switch (AsmString[LastEmitted]) {
+            case '\n':
+              AddLiteralString("\\n");
+              break;
+            case '\t':
+              // If the asm writer is not using a columnar layout, \t is not
+              // magic.
+              if (FirstOperandColumn == -1 || OperandSpacing == -1) {
+                AddLiteralString("\\t");
+              } else {
+                // We recognize a tab as an operand delimeter.
+                unsigned DestColumn = FirstOperandColumn + 
+                CurColumn++ * OperandSpacing;
+                Operands.push_back(
+                  AsmWriterOperand(
+                    "O.PadToColumn(" +
+                    utostr(DestColumn) + ");\n",
+                    AsmWriterOperand::isLiteralStatementOperand));
+              }
+              break;
+            case '"':
+              AddLiteralString("\\\"");
+              break;
+            case '\\':
+              AddLiteralString("\\\\");
+              break;
+            default:
+              AddLiteralString(std::string(1, AsmString[LastEmitted]));
+              break;
+          }
+      } else {
+        LastEmitted = DollarPos;
+      }
+    } else if (AsmString[DollarPos] == '\\') {
+      if (DollarPos+1 != AsmString.size() &&
+          (CurVariant == Variant || CurVariant == ~0U)) {
+        if (AsmString[DollarPos+1] == 'n') {
+          AddLiteralString("\\n");
+        } else if (AsmString[DollarPos+1] == 't') {
+          // If the asm writer is not using a columnar layout, \t is not
+          // magic.
+          if (FirstOperandColumn == -1 || OperandSpacing == -1) {
+            AddLiteralString("\\t");
+            break;
+          }
+          
+          // We recognize a tab as an operand delimeter.
+          unsigned DestColumn = FirstOperandColumn + 
+          CurColumn++ * OperandSpacing;
+          Operands.push_back(
+            AsmWriterOperand("O.PadToColumn(" + utostr(DestColumn) + ");\n",
+                             AsmWriterOperand::isLiteralStatementOperand));
+          break;
+        } else if (std::string("${|}\\").find(AsmString[DollarPos+1]) 
+                   != std::string::npos) {
+          AddLiteralString(std::string(1, AsmString[DollarPos+1]));
+        } else {
+          throw "Non-supported escaped character found in instruction '" +
+          CGI.TheDef->getName() + "'!";
+        }
+        LastEmitted = DollarPos+2;
+        continue;
+      }
+    } else if (AsmString[DollarPos] == '{') {
+      if (CurVariant != ~0U)
+        throw "Nested variants found for instruction '" +
+        CGI.TheDef->getName() + "'!";
+      LastEmitted = DollarPos+1;
+      CurVariant = 0;   // We are now inside of the variant!
+    } else if (AsmString[DollarPos] == '|') {
+      if (CurVariant == ~0U)
+        throw "'|' character found outside of a variant in instruction '"
+        + CGI.TheDef->getName() + "'!";
+      ++CurVariant;
+      ++LastEmitted;
+    } else if (AsmString[DollarPos] == '}') {
+      if (CurVariant == ~0U)
+        throw "'}' character found outside of a variant in instruction '"
+        + CGI.TheDef->getName() + "'!";
+      ++LastEmitted;
+      CurVariant = ~0U;
+    } else if (DollarPos+1 != AsmString.size() &&
+               AsmString[DollarPos+1] == '$') {
+      if (CurVariant == Variant || CurVariant == ~0U) {
+        AddLiteralString("$");  // "$$" -> $
+      }
+      LastEmitted = DollarPos+2;
+    } else {
+      // Get the name of the variable.
+      std::string::size_type VarEnd = DollarPos+1;
+      
+      // handle ${foo}bar as $foo by detecting whether the character following
+      // the dollar sign is a curly brace.  If so, advance VarEnd and DollarPos
+      // so the variable name does not contain the leading curly brace.
+      bool hasCurlyBraces = false;
+      if (VarEnd < AsmString.size() && '{' == AsmString[VarEnd]) {
+        hasCurlyBraces = true;
+        ++DollarPos;
+        ++VarEnd;
+      }
+      
+      while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd]))
+        ++VarEnd;
+      std::string VarName(AsmString.begin()+DollarPos+1,
+                          AsmString.begin()+VarEnd);
+      
+      // Modifier - Support ${foo:modifier} syntax, where "modifier" is passed
+      // into printOperand.  Also support ${:feature}, which is passed into
+      // PrintSpecial.
+      std::string Modifier;
+      
+      // In order to avoid starting the next string at the terminating curly
+      // brace, advance the end position past it if we found an opening curly
+      // brace.
+      if (hasCurlyBraces) {
+        if (VarEnd >= AsmString.size())
+          throw "Reached end of string before terminating curly brace in '"
+          + CGI.TheDef->getName() + "'";
+        
+        // Look for a modifier string.
+        if (AsmString[VarEnd] == ':') {
+          ++VarEnd;
+          if (VarEnd >= AsmString.size())
+            throw "Reached end of string before terminating curly brace in '"
+            + CGI.TheDef->getName() + "'";
+          
+          unsigned ModifierStart = VarEnd;
+          while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd]))
+            ++VarEnd;
+          Modifier = std::string(AsmString.begin()+ModifierStart,
+                                 AsmString.begin()+VarEnd);
+          if (Modifier.empty())
+            throw "Bad operand modifier name in '"+ CGI.TheDef->getName() + "'";
+        }
+        
+        if (AsmString[VarEnd] != '}')
+          throw "Variable name beginning with '{' did not end with '}' in '"
+          + CGI.TheDef->getName() + "'";
+        ++VarEnd;
+      }
+      if (VarName.empty() && Modifier.empty())
+        throw "Stray '$' in '" + CGI.TheDef->getName() +
+        "' asm string, maybe you want $$?";
+      
+      if (VarName.empty()) {
+        // Just a modifier, pass this into PrintSpecial.
+        Operands.push_back(AsmWriterOperand("PrintSpecial", 
+                                            ~0U, 
+                                            ~0U, 
+                                            Modifier));
+      } else {
+        // Otherwise, normal operand.
+        unsigned OpNo = CGI.getOperandNamed(VarName);
+        CodeGenInstruction::OperandInfo OpInfo = CGI.OperandList[OpNo];
+        
+        if (CurVariant == Variant || CurVariant == ~0U) {
+          unsigned MIOp = OpInfo.MIOperandNo;
+          Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName, 
+                                              OpNo,
+                                              MIOp,
+                                              Modifier));
+        }
+      }
+      LastEmitted = VarEnd;
+    }
+  }
+  
+  Operands.push_back(AsmWriterOperand("return;",
+    AsmWriterOperand::isLiteralStatementOperand));
+}
+
+/// MatchesAllButOneOp - If this instruction is exactly identical to the
+/// specified instruction except for one differing operand, return the differing
+/// operand number.  If more than one operand mismatches, return ~1, otherwise
+/// if the instructions are identical return ~0.
+unsigned AsmWriterInst::MatchesAllButOneOp(const AsmWriterInst &Other)const{
+  if (Operands.size() != Other.Operands.size()) return ~1;
+  
+  unsigned MismatchOperand = ~0U;
+  for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
+    if (Operands[i] != Other.Operands[i]) {
+      if (MismatchOperand != ~0U)  // Already have one mismatch?
+        return ~1U;
+      else
+        MismatchOperand = i;
+    }
+  }
+  return MismatchOperand;
+}
diff --git a/src/LLVM/utils/TableGen/AsmWriterInst.h b/src/LLVM/utils/TableGen/AsmWriterInst.h
new file mode 100644
index 0000000..20b8588
--- /dev/null
+++ b/src/LLVM/utils/TableGen/AsmWriterInst.h
@@ -0,0 +1,113 @@
+//===- AsmWriterInst.h - Classes encapsulating a printable inst -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These classes implement a parser for assembly strings.  The parser splits
+// the string into operands, which can be literal strings (the constant bits of
+// the string), actual operands (i.e., operands from the MachineInstr), and
+// dynamically-generated text, specified by raw C++ code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ASMWRITER_INST_H
+#define ASMWRITER_INST_H
+
+#include <string>
+#include <vector>
+
+namespace llvm {
+  class CodeGenInstruction;
+  class Record;
+  
+  struct AsmWriterOperand {
+    enum OpType {
+      // Output this text surrounded by quotes to the asm.
+      isLiteralTextOperand, 
+      // This is the name of a routine to call to print the operand.
+      isMachineInstrOperand,
+      // Output this text verbatim to the asm writer.  It is code that
+      // will output some text to the asm.
+      isLiteralStatementOperand
+    } OperandType;
+    
+    /// Str - For isLiteralTextOperand, this IS the literal text.  For
+    /// isMachineInstrOperand, this is the PrinterMethodName for the operand..
+    /// For isLiteralStatementOperand, this is the code to insert verbatim 
+    /// into the asm writer.
+    std::string Str;
+    
+    /// CGIOpNo - For isMachineInstrOperand, this is the index of the operand in
+    /// the CodeGenInstruction.
+    unsigned CGIOpNo;
+    
+    /// MiOpNo - For isMachineInstrOperand, this is the operand number of the
+    /// machine instruction.
+    unsigned MIOpNo;
+    
+    /// MiModifier - For isMachineInstrOperand, this is the modifier string for
+    /// an operand, specified with syntax like ${opname:modifier}.
+    std::string MiModifier;
+    
+    // To make VS STL happy
+    AsmWriterOperand(OpType op = isLiteralTextOperand):OperandType(op) {}
+    
+    AsmWriterOperand(const std::string &LitStr,
+                     OpType op = isLiteralTextOperand)
+    : OperandType(op), Str(LitStr) {}
+    
+    AsmWriterOperand(const std::string &Printer,
+                     unsigned _CGIOpNo,
+                     unsigned _MIOpNo,
+                     const std::string &Modifier,
+                     OpType op = isMachineInstrOperand) 
+    : OperandType(op), Str(Printer), CGIOpNo(_CGIOpNo), MIOpNo(_MIOpNo),
+    MiModifier(Modifier) {}
+    
+    bool operator!=(const AsmWriterOperand &Other) const {
+      if (OperandType != Other.OperandType || Str != Other.Str) return true;
+      if (OperandType == isMachineInstrOperand)
+        return MIOpNo != Other.MIOpNo || MiModifier != Other.MiModifier;
+      return false;
+    }
+    bool operator==(const AsmWriterOperand &Other) const {
+      return !operator!=(Other);
+    }
+    
+    /// getCode - Return the code that prints this operand.
+    std::string getCode() const;
+  };
+  
+  class AsmWriterInst {
+  public:
+    std::vector<AsmWriterOperand> Operands;
+    const CodeGenInstruction *CGI;
+    
+    AsmWriterInst(const CodeGenInstruction &CGI, 
+                  unsigned Variant,
+                  int FirstOperandColumn,
+                  int OperandSpacing);
+    
+    /// MatchesAllButOneOp - If this instruction is exactly identical to the
+    /// specified instruction except for one differing operand, return the
+    /// differing operand number.  Otherwise return ~0.
+    unsigned MatchesAllButOneOp(const AsmWriterInst &Other) const;
+    
+  private:
+    void AddLiteralString(const std::string &Str) {
+      // If the last operand was already a literal text string, append this to
+      // it, otherwise add a new operand.
+      if (!Operands.empty() &&
+          Operands.back().OperandType == AsmWriterOperand::isLiteralTextOperand)
+        Operands.back().Str.append(Str);
+      else
+        Operands.push_back(AsmWriterOperand(Str));
+    }
+  };
+}
+
+#endif
diff --git a/src/LLVM/utils/TableGen/CMakeLists.txt b/src/LLVM/utils/TableGen/CMakeLists.txt
new file mode 100644
index 0000000..972989b
--- /dev/null
+++ b/src/LLVM/utils/TableGen/CMakeLists.txt
@@ -0,0 +1,46 @@
+add_executable(tblgen
+  ARMDecoderEmitter.cpp
+  AsmMatcherEmitter.cpp
+  AsmWriterEmitter.cpp
+  AsmWriterInst.cpp
+  CallingConvEmitter.cpp
+  ClangASTNodesEmitter.cpp
+  ClangAttrEmitter.cpp
+  ClangDiagnosticsEmitter.cpp
+  CodeEmitterGen.cpp
+  CodeGenDAGPatterns.cpp
+  CodeGenInstruction.cpp
+  CodeGenTarget.cpp
+  DAGISelEmitter.cpp
+  DAGISelMatcherEmitter.cpp
+  DAGISelMatcherGen.cpp
+  DAGISelMatcherOpt.cpp
+  DAGISelMatcher.cpp
+  DisassemblerEmitter.cpp
+  EDEmitter.cpp
+  FastISelEmitter.cpp
+  InstrEnumEmitter.cpp
+  InstrInfoEmitter.cpp
+  IntrinsicEmitter.cpp
+  LLVMCConfigurationEmitter.cpp
+  NeonEmitter.cpp
+  OptParserEmitter.cpp
+  Record.cpp
+  RegisterInfoEmitter.cpp
+  SubtargetEmitter.cpp
+  TGLexer.cpp
+  TGParser.cpp
+  TGValueTypes.cpp
+  TableGen.cpp
+  TableGenBackend.cpp
+  X86DisassemblerTables.cpp
+  X86RecognizableInstr.cpp
+  )
+
+target_link_libraries(tblgen LLVMSupport LLVMSystem)
+if( MINGW )
+  target_link_libraries(tblgen imagehlp psapi)
+endif( MINGW )
+if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD AND NOT BEOS )
+  target_link_libraries(tblgen pthread)
+endif()
diff --git a/src/LLVM/utils/TableGen/CallingConvEmitter.cpp b/src/LLVM/utils/TableGen/CallingConvEmitter.cpp
new file mode 100644
index 0000000..7643609
--- /dev/null
+++ b/src/LLVM/utils/TableGen/CallingConvEmitter.cpp
@@ -0,0 +1,212 @@
+//===- CallingConvEmitter.cpp - Generate calling conventions --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend is responsible for emitting descriptions of the calling
+// conventions supported by this target.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CallingConvEmitter.h"
+#include "Record.h"
+#include "CodeGenTarget.h"
+using namespace llvm;
+
+void CallingConvEmitter::run(raw_ostream &O) {
+  EmitSourceFileHeader("Calling Convention Implementation Fragment", O);
+
+  std::vector<Record*> CCs = Records.getAllDerivedDefinitions("CallingConv");
+  
+  // Emit prototypes for all of the CC's so that they can forward ref each
+  // other.
+  for (unsigned i = 0, e = CCs.size(); i != e; ++i) {
+    O << "static bool " << CCs[i]->getName()
+      << "(unsigned ValNo, EVT ValVT,\n"
+      << std::string(CCs[i]->getName().size()+13, ' ')
+      << "EVT LocVT, CCValAssign::LocInfo LocInfo,\n"
+      << std::string(CCs[i]->getName().size()+13, ' ')
+      << "ISD::ArgFlagsTy ArgFlags, CCState &State);\n";
+  }
+  
+  // Emit each calling convention description in full.
+  for (unsigned i = 0, e = CCs.size(); i != e; ++i)
+    EmitCallingConv(CCs[i], O);
+}
+
+
+void CallingConvEmitter::EmitCallingConv(Record *CC, raw_ostream &O) {
+  ListInit *CCActions = CC->getValueAsListInit("Actions");
+  Counter = 0;
+
+  O << "\n\nstatic bool " << CC->getName()
+    << "(unsigned ValNo, EVT ValVT,\n"
+    << std::string(CC->getName().size()+13, ' ')
+    << "EVT LocVT, CCValAssign::LocInfo LocInfo,\n"
+    << std::string(CC->getName().size()+13, ' ')
+    << "ISD::ArgFlagsTy ArgFlags, CCState &State) {\n";
+  // Emit all of the actions, in order.
+  for (unsigned i = 0, e = CCActions->getSize(); i != e; ++i) {
+    O << "\n";
+    EmitAction(CCActions->getElementAsRecord(i), 2, O);
+  }
+  
+  O << "\n  return true;  // CC didn't match.\n";
+  O << "}\n";
+}
+
+void CallingConvEmitter::EmitAction(Record *Action,
+                                    unsigned Indent, raw_ostream &O) {
+  std::string IndentStr = std::string(Indent, ' ');
+  
+  if (Action->isSubClassOf("CCPredicateAction")) {
+    O << IndentStr << "if (";
+    
+    if (Action->isSubClassOf("CCIfType")) {
+      ListInit *VTs = Action->getValueAsListInit("VTs");
+      for (unsigned i = 0, e = VTs->getSize(); i != e; ++i) {
+        Record *VT = VTs->getElementAsRecord(i);
+        if (i != 0) O << " ||\n    " << IndentStr;
+        O << "LocVT == " << getEnumName(getValueType(VT));
+      }
+
+    } else if (Action->isSubClassOf("CCIf")) {
+      O << Action->getValueAsString("Predicate");
+    } else {
+      Action->dump();
+      throw "Unknown CCPredicateAction!";
+    }
+    
+    O << ") {\n";
+    EmitAction(Action->getValueAsDef("SubAction"), Indent+2, O);
+    O << IndentStr << "}\n";
+  } else {
+    if (Action->isSubClassOf("CCDelegateTo")) {
+      Record *CC = Action->getValueAsDef("CC");
+      O << IndentStr << "if (!" << CC->getName()
+        << "(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))\n"
+        << IndentStr << "  return false;\n";
+    } else if (Action->isSubClassOf("CCAssignToReg")) {
+      ListInit *RegList = Action->getValueAsListInit("RegList");
+      if (RegList->getSize() == 1) {
+        O << IndentStr << "if (unsigned Reg = State.AllocateReg(";
+        O << getQualifiedName(RegList->getElementAsRecord(0)) << ")) {\n";
+      } else {
+        O << IndentStr << "static const unsigned RegList" << ++Counter
+          << "[] = {\n";
+        O << IndentStr << "  ";
+        for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
+          if (i != 0) O << ", ";
+          O << getQualifiedName(RegList->getElementAsRecord(i));
+        }
+        O << "\n" << IndentStr << "};\n";
+        O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList"
+          << Counter << ", " << RegList->getSize() << ")) {\n";
+      }
+      O << IndentStr << "  State.addLoc(CCValAssign::getReg(ValNo, ValVT, "
+        << "Reg, LocVT, LocInfo));\n";
+      O << IndentStr << "  return false;\n";
+      O << IndentStr << "}\n";
+    } else if (Action->isSubClassOf("CCAssignToRegWithShadow")) {
+      ListInit *RegList = Action->getValueAsListInit("RegList");
+      ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList");
+      if (ShadowRegList->getSize() >0 &&
+          ShadowRegList->getSize() != RegList->getSize())
+        throw "Invalid length of list of shadowed registers";
+
+      if (RegList->getSize() == 1) {
+        O << IndentStr << "if (unsigned Reg = State.AllocateReg(";
+        O << getQualifiedName(RegList->getElementAsRecord(0));
+        O << ", " << getQualifiedName(ShadowRegList->getElementAsRecord(0));
+        O << ")) {\n";
+      } else {
+        unsigned RegListNumber = ++Counter;
+        unsigned ShadowRegListNumber = ++Counter;
+
+        O << IndentStr << "static const unsigned RegList" << RegListNumber
+          << "[] = {\n";
+        O << IndentStr << "  ";
+        for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
+          if (i != 0) O << ", ";
+          O << getQualifiedName(RegList->getElementAsRecord(i));
+        }
+        O << "\n" << IndentStr << "};\n";
+
+        O << IndentStr << "static const unsigned RegList"
+          << ShadowRegListNumber << "[] = {\n";
+        O << IndentStr << "  ";
+        for (unsigned i = 0, e = ShadowRegList->getSize(); i != e; ++i) {
+          if (i != 0) O << ", ";
+          O << getQualifiedName(ShadowRegList->getElementAsRecord(i));
+        }
+        O << "\n" << IndentStr << "};\n";
+
+        O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList"
+          << RegListNumber << ", " << "RegList" << ShadowRegListNumber
+          << ", " << RegList->getSize() << ")) {\n";
+      }
+      O << IndentStr << "  State.addLoc(CCValAssign::getReg(ValNo, ValVT, "
+        << "Reg, LocVT, LocInfo));\n";
+      O << IndentStr << "  return false;\n";
+      O << IndentStr << "}\n";
+    } else if (Action->isSubClassOf("CCAssignToStack")) {
+      int Size = Action->getValueAsInt("Size");
+      int Align = Action->getValueAsInt("Align");
+
+      O << IndentStr << "unsigned Offset" << ++Counter
+        << " = State.AllocateStack(";
+      if (Size)
+        O << Size << ", ";
+      else
+        O << "\n" << IndentStr << "  State.getTarget().getTargetData()"
+          "->getTypeAllocSize(LocVT.getTypeForEVT(State.getContext())), ";
+      if (Align)
+        O << Align;
+      else
+        O << "\n" << IndentStr << "  State.getTarget().getTargetData()"
+          "->getABITypeAlignment(LocVT.getTypeForEVT(State.getContext()))";
+      if (Action->isSubClassOf("CCAssignToStackWithShadow"))
+        O << ", " << getQualifiedName(Action->getValueAsDef("ShadowReg"));
+      O << ");\n" << IndentStr
+        << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
+        << Counter << ", LocVT, LocInfo));\n";
+      O << IndentStr << "return false;\n";
+    } else if (Action->isSubClassOf("CCPromoteToType")) {
+      Record *DestTy = Action->getValueAsDef("DestTy");
+      O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
+      O << IndentStr << "if (ArgFlags.isSExt())\n"
+        << IndentStr << IndentStr << "LocInfo = CCValAssign::SExt;\n"
+        << IndentStr << "else if (ArgFlags.isZExt())\n"
+        << IndentStr << IndentStr << "LocInfo = CCValAssign::ZExt;\n"
+        << IndentStr << "else\n"
+        << IndentStr << IndentStr << "LocInfo = CCValAssign::AExt;\n";
+    } else if (Action->isSubClassOf("CCBitConvertToType")) {
+      Record *DestTy = Action->getValueAsDef("DestTy");
+      O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
+      O << IndentStr << "LocInfo = CCValAssign::BCvt;\n";
+    } else if (Action->isSubClassOf("CCPassIndirect")) {
+      Record *DestTy = Action->getValueAsDef("DestTy");
+      O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
+      O << IndentStr << "LocInfo = CCValAssign::Indirect;\n";
+    } else if (Action->isSubClassOf("CCPassByVal")) {
+      int Size = Action->getValueAsInt("Size");
+      int Align = Action->getValueAsInt("Align");
+      O << IndentStr
+        << "State.HandleByVal(ValNo, ValVT, LocVT, LocInfo, "
+        << Size << ", " << Align << ", ArgFlags);\n";
+      O << IndentStr << "return false;\n";
+    } else if (Action->isSubClassOf("CCCustom")) {
+      O << IndentStr
+        << "if (" << Action->getValueAsString("FuncName") << "(ValNo, ValVT, "
+        << "LocVT, LocInfo, ArgFlags, State))\n";
+      O << IndentStr << IndentStr << "return false;\n";
+    } else {
+      Action->dump();
+      throw "Unknown CCAction!";
+    }
+  }
+}
diff --git a/src/LLVM/utils/TableGen/CallingConvEmitter.h b/src/LLVM/utils/TableGen/CallingConvEmitter.h
new file mode 100644
index 0000000..7fc2507
--- /dev/null
+++ b/src/LLVM/utils/TableGen/CallingConvEmitter.h
@@ -0,0 +1,38 @@
+//===- CallingConvEmitter.h - Generate calling conventions ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend is responsible for emitting descriptions of the calling
+// conventions supported by this target.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CALLINGCONV_EMITTER_H
+#define CALLINGCONV_EMITTER_H
+
+#include "TableGenBackend.h"
+#include <map>
+#include <vector>
+#include <cassert>
+
+namespace llvm {
+  class CallingConvEmitter : public TableGenBackend {
+    RecordKeeper &Records;
+  public:
+    explicit CallingConvEmitter(RecordKeeper &R) : Records(R) {}
+
+    // run - Output the asmwriter, returning true on failure.
+    void run(raw_ostream &o);
+    
+  private:
+    void EmitCallingConv(Record *CC, raw_ostream &O);
+    void EmitAction(Record *Action, unsigned Indent, raw_ostream &O);
+    unsigned Counter;
+  };
+}
+#endif
diff --git a/src/LLVM/utils/TableGen/ClangASTNodesEmitter.cpp b/src/LLVM/utils/TableGen/ClangASTNodesEmitter.cpp
new file mode 100644
index 0000000..187ab46
--- /dev/null
+++ b/src/LLVM/utils/TableGen/ClangASTNodesEmitter.cpp
@@ -0,0 +1,165 @@
+//=== ClangASTNodesEmitter.cpp - Generate Clang AST node tables -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These tablegen backends emit Clang AST node tables
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangASTNodesEmitter.h"
+#include <set>
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// Statement Node Tables (.inc file) generation.
+//===----------------------------------------------------------------------===//
+
+// Returns the first and last non-abstract subrecords
+// Called recursively to ensure that nodes remain contiguous
+std::pair<Record *, Record *> ClangASTNodesEmitter::EmitNode(
+                                                           const ChildMap &Tree,
+                                                           raw_ostream &OS,
+                                                           Record *Base) {
+  std::string BaseName = macroName(Base->getName());
+
+  ChildIterator i = Tree.lower_bound(Base), e = Tree.upper_bound(Base);
+
+  Record *First = 0, *Last = 0;
+  // This might be the pseudo-node for Stmt; don't assume it has an Abstract
+  // bit
+  if (Base->getValue("Abstract") && !Base->getValueAsBit("Abstract"))
+    First = Last = Base;
+
+  for (; i != e; ++i) {
+    Record *R = i->second;
+    bool Abstract = R->getValueAsBit("Abstract");
+    std::string NodeName = macroName(R->getName());
+
+    OS << "#ifndef " << NodeName << "\n";
+    OS << "#  define " << NodeName << "(Type, Base) "
+        << BaseName << "(Type, Base)\n";
+    OS << "#endif\n";
+
+    if (Abstract)
+      OS << "ABSTRACT_" << macroName(Root.getName()) << "(" << NodeName << "("
+          << R->getName() << ", " << baseName(*Base) << "))\n";
+    else
+      OS << NodeName << "(" << R->getName() << ", "
+          << baseName(*Base) << ")\n";
+
+    if (Tree.find(R) != Tree.end()) {
+      const std::pair<Record *, Record *> &Result
+        = EmitNode(Tree, OS, R);
+      if (!First && Result.first)
+        First = Result.first;
+      if (Result.second)
+        Last = Result.second;
+    } else {
+      if (!Abstract) {
+        Last = R;
+
+        if (!First)
+          First = R;
+      }
+    }
+
+    OS << "#undef " << NodeName << "\n\n";
+  }
+
+  if (First) {
+    assert (Last && "Got a first node but not a last node for a range!");
+    if (Base == &Root)
+      OS << "LAST_" << macroName(Root.getName()) << "_RANGE(";
+    else
+      OS << macroName(Root.getName()) << "_RANGE(";
+    OS << Base->getName() << ", " << First->getName() << ", "
+       << Last->getName() << ")\n\n";
+  }
+
+  return std::make_pair(First, Last);
+}
+
+void ClangASTNodesEmitter::run(raw_ostream &OS) {
+  // Write the preamble
+  OS << "#ifndef ABSTRACT_" << macroName(Root.getName()) << "\n";
+  OS << "#  define ABSTRACT_" << macroName(Root.getName()) << "(Type) Type\n";
+  OS << "#endif\n";
+
+  OS << "#ifndef " << macroName(Root.getName()) << "_RANGE\n";
+  OS << "#  define "
+     << macroName(Root.getName()) << "_RANGE(Base, First, Last)\n";
+  OS << "#endif\n\n";
+
+  OS << "#ifndef LAST_" << macroName(Root.getName()) << "_RANGE\n";
+  OS << "#  define LAST_" 
+     << macroName(Root.getName()) << "_RANGE(Base, First, Last) " 
+     << macroName(Root.getName()) << "_RANGE(Base, First, Last)\n";
+  OS << "#endif\n\n";
+ 
+  // Emit statements
+  const std::vector<Record*> Stmts
+    = Records.getAllDerivedDefinitions(Root.getName());
+
+  ChildMap Tree;
+
+  for (unsigned i = 0, e = Stmts.size(); i != e; ++i) {
+    Record *R = Stmts[i];
+
+    if (R->getValue("Base"))
+      Tree.insert(std::make_pair(R->getValueAsDef("Base"), R));
+    else
+      Tree.insert(std::make_pair(&Root, R));
+  }
+
+  EmitNode(Tree, OS, &Root);
+
+  OS << "#undef " << macroName(Root.getName()) << "\n";
+  OS << "#undef " << macroName(Root.getName()) << "_RANGE\n";
+  OS << "#undef LAST_" << macroName(Root.getName()) << "_RANGE\n";
+  OS << "#undef ABSTRACT_" << macroName(Root.getName()) << "\n";
+}
+
+void ClangDeclContextEmitter::run(raw_ostream &OS) {
+  // FIXME: Find a .td file format to allow for this to be represented better.
+
+  OS << "#ifndef DECL_CONTEXT\n";
+  OS << "#  define DECL_CONTEXT(DECL)\n";
+  OS << "#endif\n";
+  
+  OS << "#ifndef DECL_CONTEXT_BASE\n";
+  OS << "#  define DECL_CONTEXT_BASE(DECL) DECL_CONTEXT(DECL)\n";
+  OS << "#endif\n";
+  
+  typedef std::set<Record*> RecordSet;
+  typedef std::vector<Record*> RecordVector;
+  
+  RecordVector DeclContextsVector
+    = Records.getAllDerivedDefinitions("DeclContext");
+  RecordVector Decls = Records.getAllDerivedDefinitions("Decl");
+  RecordSet DeclContexts (DeclContextsVector.begin(), DeclContextsVector.end());
+   
+  for (RecordVector::iterator i = Decls.begin(), e = Decls.end(); i != e; ++i) {
+    Record *R = *i;
+
+    if (R->getValue("Base")) {
+      Record *B = R->getValueAsDef("Base");
+      if (DeclContexts.find(B) != DeclContexts.end()) {
+        OS << "DECL_CONTEXT_BASE(" << B->getName() << ")\n";
+        DeclContexts.erase(B);
+      }
+    }
+  }
+
+  for (RecordSet::iterator i = DeclContexts.begin(), e = DeclContexts.end();
+       i != e; ++i) {
+    OS << "DECL_CONTEXT(" << (*i)->getName() << ")\n";
+  }
+
+  OS << "#undef DECL_CONTEXT\n";
+  OS << "#undef DECL_CONTEXT_BASE\n";
+}
diff --git a/src/LLVM/utils/TableGen/ClangASTNodesEmitter.h b/src/LLVM/utils/TableGen/ClangASTNodesEmitter.h
new file mode 100644
index 0000000..abf9c9a
--- /dev/null
+++ b/src/LLVM/utils/TableGen/ClangASTNodesEmitter.h
@@ -0,0 +1,84 @@
+//===- ClangASTNodesEmitter.h - Generate Clang AST node tables -*- C++ -*--===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These tablegen backends emit Clang AST node tables
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANGAST_EMITTER_H
+#define CLANGAST_EMITTER_H
+
+#include "TableGenBackend.h"
+#include "Record.h"
+#include <string>
+#include <cctype>
+#include <map>
+
+namespace llvm {
+
+/// ClangASTNodesEmitter - The top-level class emits .inc files containing
+///  declarations of Clang statements.
+///
+class ClangASTNodesEmitter : public TableGenBackend {
+  // A map from a node to each of its derived nodes.
+  typedef std::multimap<Record*, Record*> ChildMap;
+  typedef ChildMap::const_iterator ChildIterator;
+
+  RecordKeeper &Records;
+  Record Root;
+  const std::string &BaseSuffix;
+
+  // Create a macro-ized version of a name
+  static std::string macroName(std::string S) {
+    for (unsigned i = 0; i < S.size(); ++i)
+      S[i] = std::toupper(S[i]);
+
+    return S;
+  }
+
+  // Return the name to be printed in the base field. Normally this is
+  // the record's name plus the base suffix, but if it is the root node and
+  // the suffix is non-empty, it's just the suffix.
+  std::string baseName(Record &R) {
+    if (&R == &Root && !BaseSuffix.empty())
+      return BaseSuffix;
+    
+    return R.getName() + BaseSuffix;
+  }
+
+  std::pair<Record *, Record *> EmitNode (const ChildMap &Tree, raw_ostream& OS,
+                                          Record *Base);
+public:
+  explicit ClangASTNodesEmitter(RecordKeeper &R, const std::string &N,
+                                const std::string &S)
+    : Records(R), Root(N, SMLoc()), BaseSuffix(S)
+    {}
+
+  // run - Output the .inc file contents
+  void run(raw_ostream &OS);
+};
+
+/// ClangDeclContextEmitter - Emits an addendum to a .inc file to enumerate the
+/// clang declaration contexts.
+///
+class ClangDeclContextEmitter : public TableGenBackend {
+  RecordKeeper &Records;
+
+public:
+  explicit ClangDeclContextEmitter(RecordKeeper &R)
+    : Records(R)
+  {}
+
+  // run - Output the .inc file contents
+  void run(raw_ostream &OS);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/utils/TableGen/ClangAttrEmitter.cpp b/src/LLVM/utils/TableGen/ClangAttrEmitter.cpp
new file mode 100644
index 0000000..fbdd2a7
--- /dev/null
+++ b/src/LLVM/utils/TableGen/ClangAttrEmitter.cpp
@@ -0,0 +1,84 @@
+//===- ClangAttrEmitter.cpp - Generate Clang attribute handling =-*- C++ -*--=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These tablegen backends emit Clang attribute processing code
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangAttrEmitter.h"
+#include "Record.h"
+#include <algorithm>
+
+using namespace llvm;
+
+void ClangAttrClassEmitter::run(raw_ostream &OS) {
+  OS << "// This file is generated by TableGen. Do not edit.\n\n";
+  OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n";
+  OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n\n";
+
+  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
+
+  for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
+       i != e; ++i) {
+    Record &R = **i;
+
+    if (R.getValueAsBit("DoNotEmit"))
+      continue;
+
+    OS << "class " << R.getName() << "Attr : public Attr {\n";
+
+    std::vector<Record*> Args = R.getValueAsListOfDefs("Args");
+
+    // FIXME: Handle arguments
+    assert(Args.empty() && "Can't yet handle arguments");
+
+    OS << "\n public:\n";
+    OS << "  " << R.getName() << "Attr(";
+    
+    // Arguments go here
+    
+    OS << ")\n";
+    OS << "    : Attr(attr::" << R.getName() << ")";
+
+    // Arguments go here
+    
+    OS << " {}\n\n";
+
+    OS << "  virtual Attr *clone (ASTContext &C) const;\n";
+    OS << "  static bool classof(const Attr *A) { return A->getKind() == "
+       << "attr::" << R.getName() << "; }\n";
+    OS << "  static bool classof(const " << R.getName()
+       << "Attr *) { return true; }\n";
+    OS << "};\n\n";
+  }
+
+  OS << "#endif\n";
+}
+
+void ClangAttrListEmitter::run(raw_ostream &OS) {
+  OS << "// This file is generated by TableGen. Do not edit.\n\n";
+
+  OS << "#ifndef LAST_ATTR\n";
+  OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n";
+  OS << "#endif\n\n";
+   
+  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
+  std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
+
+  if (i != e) {
+    // Move the end iterator back to emit the last attribute.
+    for(--e; i != e; ++i)
+      OS << "ATTR(" << (*i)->getName() << ")\n";
+    
+    OS << "LAST_ATTR(" << (*i)->getName() << ")\n\n";
+  }
+
+  OS << "#undef LAST_ATTR\n";
+  OS << "#undef ATTR\n";
+}
diff --git a/src/LLVM/utils/TableGen/ClangAttrEmitter.h b/src/LLVM/utils/TableGen/ClangAttrEmitter.h
new file mode 100644
index 0000000..5ce1c87
--- /dev/null
+++ b/src/LLVM/utils/TableGen/ClangAttrEmitter.h
@@ -0,0 +1,49 @@
+//===- ClangAttrEmitter.h - Generate Clang attribute handling =-*- C++ -*--===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These tablegen backends emit Clang attribute processing code
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANGATTR_EMITTER_H
+#define CLANGATTR_EMITTER_H
+
+#include "TableGenBackend.h"
+
+namespace llvm {
+
+/// ClangAttrClassEmitter - class emits the class defintions for attributes for
+///   clang.
+class ClangAttrClassEmitter : public TableGenBackend {
+  RecordKeeper &Records;
+ 
+ public:
+  explicit ClangAttrClassEmitter(RecordKeeper &R)
+    : Records(R)
+    {}
+
+  void run(raw_ostream &OS);
+};
+
+/// ClangAttrListEmitter - class emits the enumeration list for attributes for
+///   clang.
+class ClangAttrListEmitter : public TableGenBackend {
+  RecordKeeper &Records;
+
+ public:
+  explicit ClangAttrListEmitter(RecordKeeper &R)
+    : Records(R)
+    {}
+
+  void run(raw_ostream &OS);
+};
+
+}
+
+#endif
diff --git a/src/LLVM/utils/TableGen/ClangDiagnosticsEmitter.cpp b/src/LLVM/utils/TableGen/ClangDiagnosticsEmitter.cpp
new file mode 100644
index 0000000..75b6252
--- /dev/null
+++ b/src/LLVM/utils/TableGen/ClangDiagnosticsEmitter.cpp
@@ -0,0 +1,286 @@
+//=- ClangDiagnosticsEmitter.cpp - Generate Clang diagnostics tables -*- C++ -*-
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These tablegen backends emit Clang diagnostics tables.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangDiagnosticsEmitter.h"
+#include "Record.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/VectorExtras.h"
+#include <set>
+#include <map>
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// Diagnostic category computation code.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class DiagGroupParentMap {
+  std::map<const Record*, std::vector<Record*> > Mapping;
+public:
+  DiagGroupParentMap() {
+    std::vector<Record*> DiagGroups
+      = Records.getAllDerivedDefinitions("DiagGroup");
+    for (unsigned i = 0, e = DiagGroups.size(); i != e; ++i) {
+      std::vector<Record*> SubGroups =
+        DiagGroups[i]->getValueAsListOfDefs("SubGroups");
+      for (unsigned j = 0, e = SubGroups.size(); j != e; ++j)
+        Mapping[SubGroups[j]].push_back(DiagGroups[i]);
+    }
+  }
+  
+  const std::vector<Record*> &getParents(const Record *Group) {
+    return Mapping[Group];
+  }
+};
+} // end anonymous namespace.
+
+
+static std::string
+getCategoryFromDiagGroup(const Record *Group,
+                         DiagGroupParentMap &DiagGroupParents) {
+  // If the DiagGroup has a category, return it.
+  std::string CatName = Group->getValueAsString("CategoryName");
+  if (!CatName.empty()) return CatName;
+  
+  // The diag group may the subgroup of one or more other diagnostic groups,
+  // check these for a category as well.
+  const std::vector<Record*> &Parents = DiagGroupParents.getParents(Group);
+  for (unsigned i = 0, e = Parents.size(); i != e; ++i) {
+    CatName = getCategoryFromDiagGroup(Parents[i], DiagGroupParents);
+    if (!CatName.empty()) return CatName;
+  }
+  return "";
+}
+
+/// getDiagnosticCategory - Return the category that the specified diagnostic
+/// lives in.
+static std::string getDiagnosticCategory(const Record *R,
+                                         DiagGroupParentMap &DiagGroupParents) {
+  // If the diagnostic is in a group, and that group has a category, use it.
+  if (DefInit *Group = dynamic_cast<DefInit*>(R->getValueInit("Group"))) {
+    // Check the diagnostic's diag group for a category.
+    std::string CatName = getCategoryFromDiagGroup(Group->getDef(),
+                                                   DiagGroupParents);
+    if (!CatName.empty()) return CatName;
+  }
+  
+  // If the diagnostic itself has a category, get it.
+  return R->getValueAsString("CategoryName");
+}
+
+namespace {
+  class DiagCategoryIDMap {
+    StringMap<unsigned> CategoryIDs;
+    std::vector<std::string> CategoryStrings;
+  public:
+    DiagCategoryIDMap() {
+      DiagGroupParentMap ParentInfo;
+      
+      // The zero'th category is "".
+      CategoryStrings.push_back("");
+      CategoryIDs[""] = 0;
+      
+      std::vector<Record*> Diags =
+      Records.getAllDerivedDefinitions("Diagnostic");
+      for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
+        std::string Category = getDiagnosticCategory(Diags[i], ParentInfo);
+        if (Category.empty()) continue;  // Skip diags with no category.
+        
+        unsigned &ID = CategoryIDs[Category];
+        if (ID != 0) continue;  // Already seen.
+        
+        ID = CategoryStrings.size();
+        CategoryStrings.push_back(Category);
+      }
+    }
+    
+    unsigned getID(StringRef CategoryString) {
+      return CategoryIDs[CategoryString];
+    }
+    
+    typedef std::vector<std::string>::iterator iterator;
+    iterator begin() { return CategoryStrings.begin(); }
+    iterator end() { return CategoryStrings.end(); }
+  };
+} // end anonymous namespace.
+
+
+
+//===----------------------------------------------------------------------===//
+// Warning Tables (.inc file) generation.
+//===----------------------------------------------------------------------===//
+
+void ClangDiagsDefsEmitter::run(raw_ostream &OS) {
+  // Write the #if guard
+  if (!Component.empty()) {
+    std::string ComponentName = UppercaseString(Component);
+    OS << "#ifdef " << ComponentName << "START\n";
+    OS << "__" << ComponentName << "START = DIAG_START_" << ComponentName
+       << ",\n";
+    OS << "#undef " << ComponentName << "START\n";
+    OS << "#endif\n\n";
+  }
+
+  const std::vector<Record*> &Diags =
+    Records.getAllDerivedDefinitions("Diagnostic");
+  
+  DiagCategoryIDMap CategoryIDs;
+  DiagGroupParentMap DGParentMap;
+
+  for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
+    const Record &R = *Diags[i];
+    // Filter by component.
+    if (!Component.empty() && Component != R.getValueAsString("Component"))
+      continue;
+    
+    OS << "DIAG(" << R.getName() << ", ";
+    OS << R.getValueAsDef("Class")->getName();
+    OS << ", diag::" << R.getValueAsDef("DefaultMapping")->getName();
+    
+    // Description string.
+    OS << ", \"";
+    OS.write_escaped(R.getValueAsString("Text")) << '"';
+    
+    // Warning associated with the diagnostic.
+    if (DefInit *DI = dynamic_cast<DefInit*>(R.getValueInit("Group"))) {
+      OS << ", \"";
+      OS.write_escaped(DI->getDef()->getValueAsString("GroupName")) << '"';
+    } else {
+      OS << ", 0";
+    }
+
+    // SFINAE bit
+    if (R.getValueAsBit("SFINAE"))
+      OS << ", true";
+    else
+      OS << ", false";
+    
+    // Category number.
+    OS << ", " << CategoryIDs.getID(getDiagnosticCategory(&R, DGParentMap));
+    OS << ")\n";
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Warning Group Tables generation
+//===----------------------------------------------------------------------===//
+
+struct GroupInfo {
+  std::vector<const Record*> DiagsInGroup;
+  std::vector<std::string> SubGroups;
+  unsigned IDNo;
+};
+
+void ClangDiagGroupsEmitter::run(raw_ostream &OS) {
+  // Compute a mapping from a DiagGroup to all of its parents.
+  DiagGroupParentMap DGParentMap;
+  
+  // Invert the 1-[0/1] mapping of diags to group into a one to many mapping of
+  // groups to diags in the group.
+  std::map<std::string, GroupInfo> DiagsInGroup;
+  
+  std::vector<Record*> Diags =
+    Records.getAllDerivedDefinitions("Diagnostic");
+  for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
+    const Record *R = Diags[i];
+    DefInit *DI = dynamic_cast<DefInit*>(R->getValueInit("Group"));
+    if (DI == 0) continue;
+    std::string GroupName = DI->getDef()->getValueAsString("GroupName");
+    DiagsInGroup[GroupName].DiagsInGroup.push_back(R);
+  }
+  
+  // Add all DiagGroup's to the DiagsInGroup list to make sure we pick up empty
+  // groups (these are warnings that GCC supports that clang never produces).
+  std::vector<Record*> DiagGroups
+    = Records.getAllDerivedDefinitions("DiagGroup");
+  for (unsigned i = 0, e = DiagGroups.size(); i != e; ++i) {
+    Record *Group = DiagGroups[i];
+    GroupInfo &GI = DiagsInGroup[Group->getValueAsString("GroupName")];
+    
+    std::vector<Record*> SubGroups = Group->getValueAsListOfDefs("SubGroups");
+    for (unsigned j = 0, e = SubGroups.size(); j != e; ++j)
+      GI.SubGroups.push_back(SubGroups[j]->getValueAsString("GroupName"));
+  }
+  
+  // Assign unique ID numbers to the groups.
+  unsigned IDNo = 0;
+  for (std::map<std::string, GroupInfo>::iterator
+       I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I, ++IDNo)
+    I->second.IDNo = IDNo;
+  
+  // Walk through the groups emitting an array for each diagnostic of the diags
+  // that are mapped to.
+  OS << "\n#ifdef GET_DIAG_ARRAYS\n";
+  unsigned MaxLen = 0;
+  for (std::map<std::string, GroupInfo>::iterator
+       I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) {
+    MaxLen = std::max(MaxLen, (unsigned)I->first.size());
+    
+    std::vector<const Record*> &V = I->second.DiagsInGroup;
+    if (!V.empty()) {
+      OS << "static const short DiagArray" << I->second.IDNo << "[] = { ";
+      for (unsigned i = 0, e = V.size(); i != e; ++i)
+        OS << "diag::" << V[i]->getName() << ", ";
+      OS << "-1 };\n";
+    }
+    
+    const std::vector<std::string> &SubGroups = I->second.SubGroups;
+    if (!SubGroups.empty()) {
+      OS << "static const short DiagSubGroup" << I->second.IDNo << "[] = { ";
+      for (unsigned i = 0, e = SubGroups.size(); i != e; ++i) {
+        std::map<std::string, GroupInfo>::iterator RI =
+          DiagsInGroup.find(SubGroups[i]);
+        assert(RI != DiagsInGroup.end() && "Referenced without existing?");
+        OS << RI->second.IDNo << ", ";
+      }
+      OS << "-1 };\n";
+    }
+  }
+  OS << "#endif // GET_DIAG_ARRAYS\n\n";
+  
+  // Emit the table now.
+  OS << "\n#ifdef GET_DIAG_TABLE\n";
+  for (std::map<std::string, GroupInfo>::iterator
+       I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) {
+    // Group option string.
+    OS << "  { \"";
+    OS.write_escaped(I->first) << "\","
+                               << std::string(MaxLen-I->first.size()+1, ' ');
+    
+    // Diagnostics in the group.
+    if (I->second.DiagsInGroup.empty())
+      OS << "0, ";
+    else
+      OS << "DiagArray" << I->second.IDNo << ", ";
+    
+    // Subgroups.
+    if (I->second.SubGroups.empty())
+      OS << 0;
+    else
+      OS << "DiagSubGroup" << I->second.IDNo;
+    OS << " },\n";
+  }
+  OS << "#endif // GET_DIAG_TABLE\n\n";
+  
+  // Emit the category table next.
+  DiagCategoryIDMap CategoriesByID;
+  OS << "\n#ifdef GET_CATEGORY_TABLE\n";
+  for (DiagCategoryIDMap::iterator I = CategoriesByID.begin(),
+       E = CategoriesByID.end(); I != E; ++I)
+    OS << "CATEGORY(\"" << *I << "\")\n";
+  OS << "#endif // GET_CATEGORY_TABLE\n\n";
+}
diff --git a/src/LLVM/utils/TableGen/ClangDiagnosticsEmitter.h b/src/LLVM/utils/TableGen/ClangDiagnosticsEmitter.h
new file mode 100644
index 0000000..edd062a
--- /dev/null
+++ b/src/LLVM/utils/TableGen/ClangDiagnosticsEmitter.h
@@ -0,0 +1,46 @@
+//===- ClangDiagnosticsEmitter.h - Generate Clang diagnostics tables -*- C++ -*-
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These tablegen backends emit Clang diagnostics tables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANGDIAGS_EMITTER_H
+#define CLANGDIAGS_EMITTER_H
+
+#include "TableGenBackend.h"
+
+namespace llvm {
+
+/// ClangDiagsDefsEmitter - The top-level class emits .def files containing
+///  declarations of Clang diagnostics.
+///
+class ClangDiagsDefsEmitter : public TableGenBackend {
+  RecordKeeper &Records;
+  const std::string& Component;
+public:
+  explicit ClangDiagsDefsEmitter(RecordKeeper &R, const std::string& component)
+    : Records(R), Component(component) {}
+
+  // run - Output the .def file contents
+  void run(raw_ostream &OS);
+};
+
+class ClangDiagGroupsEmitter : public TableGenBackend {
+    RecordKeeper &Records;
+public:
+  explicit ClangDiagGroupsEmitter(RecordKeeper &R) : Records(R) {}
+    
+  void run(raw_ostream &OS);
+};
+
+  
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/utils/TableGen/CodeEmitterGen.cpp b/src/LLVM/utils/TableGen/CodeEmitterGen.cpp
new file mode 100644
index 0000000..ec702c2
--- /dev/null
+++ b/src/LLVM/utils/TableGen/CodeEmitterGen.cpp
@@ -0,0 +1,224 @@
+//===- CodeEmitterGen.cpp - Code Emitter Generator ------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// CodeEmitterGen uses the descriptions of instructions and their fields to
+// construct an automated code emitter: a function that, given a MachineInstr,
+// returns the (currently, 32-bit unsigned) value of the instruction.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeEmitterGen.h"
+#include "CodeGenTarget.h"
+#include "Record.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Debug.h"
+using namespace llvm;
+
+void CodeEmitterGen::reverseBits(std::vector<Record*> &Insts) {
+  for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end();
+       I != E; ++I) {
+    Record *R = *I;
+    if (R->getValueAsString("Namespace") == "TargetOpcode")
+      continue;
+
+    BitsInit *BI = R->getValueAsBitsInit("Inst");
+
+    unsigned numBits = BI->getNumBits();
+    BitsInit *NewBI = new BitsInit(numBits);
+    for (unsigned bit = 0, end = numBits / 2; bit != end; ++bit) {
+      unsigned bitSwapIdx = numBits - bit - 1;
+      Init *OrigBit = BI->getBit(bit);
+      Init *BitSwap = BI->getBit(bitSwapIdx);
+      NewBI->setBit(bit, BitSwap);
+      NewBI->setBit(bitSwapIdx, OrigBit);
+    }
+    if (numBits % 2) {
+      unsigned middle = (numBits + 1) / 2;
+      NewBI->setBit(middle, BI->getBit(middle));
+    }
+    
+    // Update the bits in reversed order so that emitInstrOpBits will get the
+    // correct endianness.
+    R->getValue("Inst")->setValue(NewBI);
+  }
+}
+
+
+// If the VarBitInit at position 'bit' matches the specified variable then
+// return the variable bit position.  Otherwise return -1.
+int CodeEmitterGen::getVariableBit(const std::string &VarName,
+            BitsInit *BI, int bit) {
+  if (VarBitInit *VBI = dynamic_cast<VarBitInit*>(BI->getBit(bit))) {
+    TypedInit *TI = VBI->getVariable();
+    
+    if (VarInit *VI = dynamic_cast<VarInit*>(TI)) {
+      if (VI->getName() == VarName) return VBI->getBitNum();
+    }
+  }
+  
+  return -1;
+} 
+
+
+void CodeEmitterGen::run(raw_ostream &o) {
+  CodeGenTarget Target;
+  std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
+  
+  // For little-endian instruction bit encodings, reverse the bit order
+  if (Target.isLittleEndianEncoding()) reverseBits(Insts);
+
+  EmitSourceFileHeader("Machine Code Emitter", o);
+  std::string Namespace = Insts[0]->getValueAsString("Namespace") + "::";
+  
+  const std::vector<const CodeGenInstruction*> &NumberedInstructions =
+    Target.getInstructionsByEnumValue();
+
+  // Emit function declaration
+  o << "unsigned " << Target.getName() << "CodeEmitter::"
+    << "getBinaryCodeForInstr(const MachineInstr &MI) {\n";
+
+  // Emit instruction base values
+  o << "  static const unsigned InstBits[] = {\n";
+  for (std::vector<const CodeGenInstruction*>::const_iterator
+          IN = NumberedInstructions.begin(),
+          EN = NumberedInstructions.end();
+       IN != EN; ++IN) {
+    const CodeGenInstruction *CGI = *IN;
+    Record *R = CGI->TheDef;
+    
+    if (R->getValueAsString("Namespace") == "TargetOpcode") {
+      o << "    0U,\n";
+      continue;
+    }
+    
+    BitsInit *BI = R->getValueAsBitsInit("Inst");
+
+    // Start by filling in fixed values...
+    unsigned Value = 0;
+    for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) {
+      if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(e-i-1))) {
+        Value |= B->getValue() << (e-i-1);
+      }
+    }
+    o << "    " << Value << "U," << '\t' << "// " << R->getName() << "\n";
+  }
+  o << "    0U\n  };\n";
+  
+  // Map to accumulate all the cases.
+  std::map<std::string, std::vector<std::string> > CaseMap;
+  
+  // Construct all cases statement for each opcode
+  for (std::vector<Record*>::iterator IC = Insts.begin(), EC = Insts.end();
+        IC != EC; ++IC) {
+    Record *R = *IC;
+    if (R->getValueAsString("Namespace") == "TargetOpcode")
+      continue;
+    const std::string &InstName = R->getName();
+    std::string Case("");
+
+    BitsInit *BI = R->getValueAsBitsInit("Inst");
+    const std::vector<RecordVal> &Vals = R->getValues();
+    CodeGenInstruction &CGI = Target.getInstruction(R);
+    
+    // Loop over all of the fields in the instruction, determining which are the
+    // operands to the instruction.
+    unsigned op = 0;
+    for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
+      if (!Vals[i].getPrefix() && !Vals[i].getValue()->isComplete()) {
+        // Is the operand continuous? If so, we can just mask and OR it in
+        // instead of doing it bit-by-bit, saving a lot in runtime cost.
+        const std::string &VarName = Vals[i].getName();
+        bool gotOp = false;
+        
+        for (int bit = BI->getNumBits()-1; bit >= 0; ) {
+          int varBit = getVariableBit(VarName, BI, bit);
+          
+          if (varBit == -1) {
+            --bit;
+          } else {
+            int beginInstBit = bit;
+            int beginVarBit = varBit;
+            int N = 1;
+            
+            for (--bit; bit >= 0;) {
+              varBit = getVariableBit(VarName, BI, bit);
+              if (varBit == -1 || varBit != (beginVarBit - N)) break;
+              ++N;
+              --bit;
+            }
+
+            if (!gotOp) {
+              /// If this operand is not supposed to be emitted by the generated
+              /// emitter, skip it.
+              while (CGI.isFlatOperandNotEmitted(op))
+                ++op;
+              
+              Case += "      // op: " + VarName + "\n"
+                   +  "      op = getMachineOpValue(MI, MI.getOperand("
+                   +  utostr(op++) + "));\n";
+              gotOp = true;
+            }
+            
+            unsigned opMask = ~0U >> (32-N);
+            int opShift = beginVarBit - N + 1;
+            opMask <<= opShift;
+            opShift = beginInstBit - beginVarBit;
+            
+            if (opShift > 0) {
+              Case += "      Value |= (op & " + utostr(opMask) + "U) << "
+                   +  itostr(opShift) + ";\n";
+            } else if (opShift < 0) {
+              Case += "      Value |= (op & " + utostr(opMask) + "U) >> "
+                   +  itostr(-opShift) + ";\n";
+            } else {
+              Case += "      Value |= op & " + utostr(opMask) + "U;\n";
+            }
+          }
+        }
+      }
+    }
+
+    std::vector<std::string> &InstList = CaseMap[Case];
+    InstList.push_back(InstName);
+  }
+
+
+  // Emit initial function code
+  o << "  const unsigned opcode = MI.getOpcode();\n"
+    << "  unsigned Value = InstBits[opcode];\n"
+    << "  unsigned op = 0;\n"
+    << "  op = op;  // suppress warning\n"
+    << "  switch (opcode) {\n";
+
+  // Emit each case statement
+  std::map<std::string, std::vector<std::string> >::iterator IE, EE;
+  for (IE = CaseMap.begin(), EE = CaseMap.end(); IE != EE; ++IE) {
+    const std::string &Case = IE->first;
+    std::vector<std::string> &InstList = IE->second;
+
+    for (int i = 0, N = InstList.size(); i < N; i++) {
+      if (i) o << "\n";
+      o << "    case " << Namespace << InstList[i]  << ":";
+    }
+    o << " {\n";
+    o << Case;
+    o << "      break;\n"
+      << "    }\n";
+  }
+
+  // Default case: unhandled opcode
+  o << "  default:\n"
+    << "    std::string msg;\n"
+    << "    raw_string_ostream Msg(msg);\n"
+    << "    Msg << \"Not supported instr: \" << MI;\n"
+    << "    report_fatal_error(Msg.str());\n"
+    << "  }\n"
+    << "  return Value;\n"
+    << "}\n\n";
+}
diff --git a/src/LLVM/utils/TableGen/CodeEmitterGen.h b/src/LLVM/utils/TableGen/CodeEmitterGen.h
new file mode 100644
index 0000000..f0b3229
--- /dev/null
+++ b/src/LLVM/utils/TableGen/CodeEmitterGen.h
@@ -0,0 +1,43 @@
+//===- CodeEmitterGen.h - Code Emitter Generator ----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// FIXME: document
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CODEMITTERGEN_H
+#define CODEMITTERGEN_H
+
+#include "TableGenBackend.h"
+#include <map>
+#include <vector>
+#include <string>
+
+namespace llvm {
+
+class RecordVal;
+class BitsInit;
+
+class CodeEmitterGen : public TableGenBackend {
+  RecordKeeper &Records;
+public:
+  CodeEmitterGen(RecordKeeper &R) : Records(R) {}
+
+  // run - Output the code emitter
+  void run(raw_ostream &o);
+private:
+  void emitMachineOpEmitter(raw_ostream &o, const std::string &Namespace);
+  void emitGetValueBit(raw_ostream &o, const std::string &Namespace);
+  void reverseBits(std::vector<Record*> &Insts);
+  int getVariableBit(const std::string &VarName, BitsInit *BI, int bit);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/utils/TableGen/CodeGenDAGPatterns.cpp b/src/LLVM/utils/TableGen/CodeGenDAGPatterns.cpp
new file mode 100644
index 0000000..303aa6c
--- /dev/null
+++ b/src/LLVM/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -0,0 +1,3021 @@
+//===- CodeGenDAGPatterns.cpp - Read DAG patterns from .td file -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the CodeGenDAGPatterns class, which is used to read and
+// represent the patterns present in a .td file for instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenDAGPatterns.h"
+#include "Record.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Debug.h"
+#include <set>
+#include <algorithm>
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+//  EEVT::TypeSet Implementation
+//===----------------------------------------------------------------------===//
+
+static inline bool isInteger(MVT::SimpleValueType VT) {
+  return EVT(VT).isInteger();
+}
+static inline bool isFloatingPoint(MVT::SimpleValueType VT) {
+  return EVT(VT).isFloatingPoint();
+}
+static inline bool isVector(MVT::SimpleValueType VT) {
+  return EVT(VT).isVector();
+}
+static inline bool isScalar(MVT::SimpleValueType VT) {
+  return !EVT(VT).isVector();
+}
+
+EEVT::TypeSet::TypeSet(MVT::SimpleValueType VT, TreePattern &TP) {
+  if (VT == MVT::iAny)
+    EnforceInteger(TP);
+  else if (VT == MVT::fAny)
+    EnforceFloatingPoint(TP);
+  else if (VT == MVT::vAny)
+    EnforceVector(TP);
+  else {
+    assert((VT < MVT::LAST_VALUETYPE || VT == MVT::iPTR ||
+            VT == MVT::iPTRAny) && "Not a concrete type!");
+    TypeVec.push_back(VT);
+  }
+}
+
+
+EEVT::TypeSet::TypeSet(const std::vector<MVT::SimpleValueType> &VTList) {
+  assert(!VTList.empty() && "empty list?");
+  TypeVec.append(VTList.begin(), VTList.end());
+  
+  if (!VTList.empty())
+    assert(VTList[0] != MVT::iAny && VTList[0] != MVT::vAny &&
+           VTList[0] != MVT::fAny);
+  
+  // Verify no duplicates.
+  array_pod_sort(TypeVec.begin(), TypeVec.end());
+  assert(std::unique(TypeVec.begin(), TypeVec.end()) == TypeVec.end());
+}
+
+/// FillWithPossibleTypes - Set to all legal types and return true, only valid
+/// on completely unknown type sets.
+bool EEVT::TypeSet::FillWithPossibleTypes(TreePattern &TP,
+                                          bool (*Pred)(MVT::SimpleValueType),
+                                          const char *PredicateName) {
+  assert(isCompletelyUnknown());
+  const std::vector<MVT::SimpleValueType> &LegalTypes = 
+    TP.getDAGPatterns().getTargetInfo().getLegalValueTypes();
+  
+  for (unsigned i = 0, e = LegalTypes.size(); i != e; ++i)
+    if (Pred == 0 || Pred(LegalTypes[i]))
+      TypeVec.push_back(LegalTypes[i]);
+
+  // If we have nothing that matches the predicate, bail out.
+  if (TypeVec.empty())
+    TP.error("Type inference contradiction found, no " +
+             std::string(PredicateName) + " types found");  
+  // No need to sort with one element.
+  if (TypeVec.size() == 1) return true;
+
+  // Remove duplicates.
+  array_pod_sort(TypeVec.begin(), TypeVec.end());
+  TypeVec.erase(std::unique(TypeVec.begin(), TypeVec.end()), TypeVec.end());
+  
+  return true;
+}
+
+/// hasIntegerTypes - Return true if this TypeSet contains iAny or an
+/// integer value type.
+bool EEVT::TypeSet::hasIntegerTypes() const {
+  for (unsigned i = 0, e = TypeVec.size(); i != e; ++i)
+    if (isInteger(TypeVec[i]))
+      return true;
+  return false;
+}  
+
+/// hasFloatingPointTypes - Return true if this TypeSet contains an fAny or
+/// a floating point value type.
+bool EEVT::TypeSet::hasFloatingPointTypes() const {
+  for (unsigned i = 0, e = TypeVec.size(); i != e; ++i)
+    if (isFloatingPoint(TypeVec[i]))
+      return true;
+  return false;
+}  
+
+/// hasVectorTypes - Return true if this TypeSet contains a vAny or a vector
+/// value type.
+bool EEVT::TypeSet::hasVectorTypes() const {
+  for (unsigned i = 0, e = TypeVec.size(); i != e; ++i)
+    if (isVector(TypeVec[i]))
+      return true;
+  return false;
+}
+
+
+std::string EEVT::TypeSet::getName() const {
+  if (TypeVec.empty()) return "<empty>";
+  
+  std::string Result;
+    
+  for (unsigned i = 0, e = TypeVec.size(); i != e; ++i) {
+    std::string VTName = llvm::getEnumName(TypeVec[i]);
+    // Strip off MVT:: prefix if present.
+    if (VTName.substr(0,5) == "MVT::")
+      VTName = VTName.substr(5);
+    if (i) Result += ':';
+    Result += VTName;
+  }
+  
+  if (TypeVec.size() == 1)
+    return Result;
+  return "{" + Result + "}";
+}
+
+/// MergeInTypeInfo - This merges in type information from the specified
+/// argument.  If 'this' changes, it returns true.  If the two types are
+/// contradictory (e.g. merge f32 into i32) then this throws an exception.
+bool EEVT::TypeSet::MergeInTypeInfo(const EEVT::TypeSet &InVT, TreePattern &TP){
+  if (InVT.isCompletelyUnknown() || *this == InVT)
+    return false;
+  
+  if (isCompletelyUnknown()) {
+    *this = InVT;
+    return true;
+  }
+  
+  assert(TypeVec.size() >= 1 && InVT.TypeVec.size() >= 1 && "No unknowns");
+  
+  // Handle the abstract cases, seeing if we can resolve them better.
+  switch (TypeVec[0]) {
+  default: break;
+  case MVT::iPTR:
+  case MVT::iPTRAny:
+    if (InVT.hasIntegerTypes()) {
+      EEVT::TypeSet InCopy(InVT);
+      InCopy.EnforceInteger(TP);
+      InCopy.EnforceScalar(TP);
+      
+      if (InCopy.isConcrete()) {
+        // If the RHS has one integer type, upgrade iPTR to i32.
+        TypeVec[0] = InVT.TypeVec[0];
+        return true;
+      }
+      
+      // If the input has multiple scalar integers, this doesn't add any info.
+      if (!InCopy.isCompletelyUnknown())
+        return false;
+    }
+    break;
+  }
+  
+  // If the input constraint is iAny/iPTR and this is an integer type list,
+  // remove non-integer types from the list.
+  if ((InVT.TypeVec[0] == MVT::iPTR || InVT.TypeVec[0] == MVT::iPTRAny) &&
+      hasIntegerTypes()) {
+    bool MadeChange = EnforceInteger(TP);
+    
+    // If we're merging in iPTR/iPTRAny and the node currently has a list of
+    // multiple different integer types, replace them with a single iPTR.
+    if ((InVT.TypeVec[0] == MVT::iPTR || InVT.TypeVec[0] == MVT::iPTRAny) &&
+        TypeVec.size() != 1) {
+      TypeVec.resize(1);
+      TypeVec[0] = InVT.TypeVec[0];
+      MadeChange = true;
+    }
+    
+    return MadeChange;
+  }
+  
+  // If this is a type list and the RHS is a typelist as well, eliminate entries
+  // from this list that aren't in the other one.
+  bool MadeChange = false;
+  TypeSet InputSet(*this);
+
+  for (unsigned i = 0; i != TypeVec.size(); ++i) {
+    bool InInVT = false;
+    for (unsigned j = 0, e = InVT.TypeVec.size(); j != e; ++j)
+      if (TypeVec[i] == InVT.TypeVec[j]) {
+        InInVT = true;
+        break;
+      }
+    
+    if (InInVT) continue;
+    TypeVec.erase(TypeVec.begin()+i--);
+    MadeChange = true;
+  }
+  
+  // If we removed all of our types, we have a type contradiction.
+  if (!TypeVec.empty())
+    return MadeChange;
+  
+  // FIXME: Really want an SMLoc here!
+  TP.error("Type inference contradiction found, merging '" +
+           InVT.getName() + "' into '" + InputSet.getName() + "'");
+  return true; // unreachable
+}
+
+/// EnforceInteger - Remove all non-integer types from this set.
+bool EEVT::TypeSet::EnforceInteger(TreePattern &TP) {
+  // If we know nothing, then get the full set.
+  if (TypeVec.empty())
+    return FillWithPossibleTypes(TP, isInteger, "integer");
+  if (!hasFloatingPointTypes())
+    return false;
+
+  TypeSet InputSet(*this);
+  
+  // Filter out all the fp types.
+  for (unsigned i = 0; i != TypeVec.size(); ++i)
+    if (!isInteger(TypeVec[i]))
+      TypeVec.erase(TypeVec.begin()+i--);
+  
+  if (TypeVec.empty())
+    TP.error("Type inference contradiction found, '" +
+             InputSet.getName() + "' needs to be integer");
+  return true;
+}
+
+/// EnforceFloatingPoint - Remove all integer types from this set.
+bool EEVT::TypeSet::EnforceFloatingPoint(TreePattern &TP) {
+  // If we know nothing, then get the full set.
+  if (TypeVec.empty())
+    return FillWithPossibleTypes(TP, isFloatingPoint, "floating point");
+
+  if (!hasIntegerTypes())
+    return false;
+
+  TypeSet InputSet(*this);
+  
+  // Filter out all the fp types.
+  for (unsigned i = 0; i != TypeVec.size(); ++i)
+    if (!isFloatingPoint(TypeVec[i]))
+      TypeVec.erase(TypeVec.begin()+i--);
+  
+  if (TypeVec.empty())
+    TP.error("Type inference contradiction found, '" +
+             InputSet.getName() + "' needs to be floating point");
+  return true;
+}
+
+/// EnforceScalar - Remove all vector types from this.
+bool EEVT::TypeSet::EnforceScalar(TreePattern &TP) {
+  // If we know nothing, then get the full set.
+  if (TypeVec.empty())
+    return FillWithPossibleTypes(TP, isScalar, "scalar");
+
+  if (!hasVectorTypes())
+    return false;
+
+  TypeSet InputSet(*this);
+  
+  // Filter out all the vector types.
+  for (unsigned i = 0; i != TypeVec.size(); ++i)
+    if (!isScalar(TypeVec[i]))
+      TypeVec.erase(TypeVec.begin()+i--);
+  
+  if (TypeVec.empty())
+    TP.error("Type inference contradiction found, '" +
+             InputSet.getName() + "' needs to be scalar");
+  return true;
+}
+
+/// EnforceVector - Remove all vector types from this.
+bool EEVT::TypeSet::EnforceVector(TreePattern &TP) {
+  // If we know nothing, then get the full set.
+  if (TypeVec.empty())
+    return FillWithPossibleTypes(TP, isVector, "vector");
+
+  TypeSet InputSet(*this);
+  bool MadeChange = false;
+  
+  // Filter out all the scalar types.
+  for (unsigned i = 0; i != TypeVec.size(); ++i)
+    if (!isVector(TypeVec[i])) {
+      TypeVec.erase(TypeVec.begin()+i--);
+      MadeChange = true;
+    }
+  
+  if (TypeVec.empty())
+    TP.error("Type inference contradiction found, '" +
+             InputSet.getName() + "' needs to be a vector");
+  return MadeChange;
+}
+
+
+
+/// EnforceSmallerThan - 'this' must be a smaller VT than Other.  Update
+/// this an other based on this information.
+bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) {
+  // Both operands must be integer or FP, but we don't care which.
+  bool MadeChange = false;
+  
+  if (isCompletelyUnknown())
+    MadeChange = FillWithPossibleTypes(TP);
+
+  if (Other.isCompletelyUnknown())
+    MadeChange = Other.FillWithPossibleTypes(TP);
+    
+  // If one side is known to be integer or known to be FP but the other side has
+  // no information, get at least the type integrality info in there.
+  if (!hasFloatingPointTypes())
+    MadeChange |= Other.EnforceInteger(TP);
+  else if (!hasIntegerTypes())
+    MadeChange |= Other.EnforceFloatingPoint(TP);
+  if (!Other.hasFloatingPointTypes())
+    MadeChange |= EnforceInteger(TP);
+  else if (!Other.hasIntegerTypes())
+    MadeChange |= EnforceFloatingPoint(TP);
+  
+  assert(!isCompletelyUnknown() && !Other.isCompletelyUnknown() &&
+         "Should have a type list now");
+  
+  // If one contains vectors but the other doesn't pull vectors out.
+  if (!hasVectorTypes())
+    MadeChange |= Other.EnforceScalar(TP);
+  if (!hasVectorTypes())
+    MadeChange |= EnforceScalar(TP);
+  
+  // This code does not currently handle nodes which have multiple types,
+  // where some types are integer, and some are fp.  Assert that this is not
+  // the case.
+  assert(!(hasIntegerTypes() && hasFloatingPointTypes()) &&
+         !(Other.hasIntegerTypes() && Other.hasFloatingPointTypes()) &&
+         "SDTCisOpSmallerThanOp does not handle mixed int/fp types!");
+  
+  // Okay, find the smallest type from the current set and remove it from the
+  // largest set.
+  MVT::SimpleValueType Smallest = TypeVec[0];
+  for (unsigned i = 1, e = TypeVec.size(); i != e; ++i)
+    if (TypeVec[i] < Smallest)
+      Smallest = TypeVec[i];
+  
+  // If this is the only type in the large set, the constraint can never be
+  // satisfied.
+  if (Other.TypeVec.size() == 1 && Other.TypeVec[0] == Smallest)
+    TP.error("Type inference contradiction found, '" +
+             Other.getName() + "' has nothing larger than '" + getName() +"'!");
+  
+  SmallVector<MVT::SimpleValueType, 2>::iterator TVI =
+    std::find(Other.TypeVec.begin(), Other.TypeVec.end(), Smallest);
+  if (TVI != Other.TypeVec.end()) {
+    Other.TypeVec.erase(TVI);
+    MadeChange = true;
+  }
+  
+  // Okay, find the largest type in the Other set and remove it from the
+  // current set.
+  MVT::SimpleValueType Largest = Other.TypeVec[0];
+  for (unsigned i = 1, e = Other.TypeVec.size(); i != e; ++i)
+    if (Other.TypeVec[i] > Largest)
+      Largest = Other.TypeVec[i];
+  
+  // If this is the only type in the small set, the constraint can never be
+  // satisfied.
+  if (TypeVec.size() == 1 && TypeVec[0] == Largest)
+    TP.error("Type inference contradiction found, '" +
+             getName() + "' has nothing smaller than '" + Other.getName()+"'!");
+  
+  TVI = std::find(TypeVec.begin(), TypeVec.end(), Largest);
+  if (TVI != TypeVec.end()) {
+    TypeVec.erase(TVI);
+    MadeChange = true;
+  }
+  
+  return MadeChange;
+}
+
+/// EnforceVectorEltTypeIs - 'this' is now constrainted to be a vector type
+/// whose element is specified by VTOperand.
+bool EEVT::TypeSet::EnforceVectorEltTypeIs(EEVT::TypeSet &VTOperand,
+                                           TreePattern &TP) {
+  // "This" must be a vector and "VTOperand" must be a scalar.
+  bool MadeChange = false;
+  MadeChange |= EnforceVector(TP);
+  MadeChange |= VTOperand.EnforceScalar(TP);
+
+  // If we know the vector type, it forces the scalar to agree.
+  if (isConcrete()) {
+    EVT IVT = getConcrete();
+    IVT = IVT.getVectorElementType();
+    return MadeChange | 
+      VTOperand.MergeInTypeInfo(IVT.getSimpleVT().SimpleTy, TP);
+  }
+
+  // If the scalar type is known, filter out vector types whose element types
+  // disagree.
+  if (!VTOperand.isConcrete())
+    return MadeChange;
+  
+  MVT::SimpleValueType VT = VTOperand.getConcrete();
+  
+  TypeSet InputSet(*this);
+  
+  // Filter out all the types which don't have the right element type.
+  for (unsigned i = 0; i != TypeVec.size(); ++i) {
+    assert(isVector(TypeVec[i]) && "EnforceVector didn't work");
+    if (EVT(TypeVec[i]).getVectorElementType().getSimpleVT().SimpleTy != VT) {
+      TypeVec.erase(TypeVec.begin()+i--);
+      MadeChange = true;
+    }
+  }
+  
+  if (TypeVec.empty())  // FIXME: Really want an SMLoc here!
+    TP.error("Type inference contradiction found, forcing '" +
+             InputSet.getName() + "' to have a vector element");
+  return MadeChange;
+}
+
+//===----------------------------------------------------------------------===//
+// Helpers for working with extended types.
+
+bool RecordPtrCmp::operator()(const Record *LHS, const Record *RHS) const {
+  return LHS->getID() < RHS->getID();
+}
+
+/// Dependent variable map for CodeGenDAGPattern variant generation
+typedef std::map<std::string, int> DepVarMap;
+
+/// Const iterator shorthand for DepVarMap
+typedef DepVarMap::const_iterator DepVarMap_citer;
+
+namespace {
+void FindDepVarsOf(TreePatternNode *N, DepVarMap &DepMap) {
+  if (N->isLeaf()) {
+    if (dynamic_cast<DefInit*>(N->getLeafValue()) != NULL) {
+      DepMap[N->getName()]++;
+    }
+  } else {
+    for (size_t i = 0, e = N->getNumChildren(); i != e; ++i)
+      FindDepVarsOf(N->getChild(i), DepMap);
+  }
+}
+
+//! Find dependent variables within child patterns
+/*!
+ */
+void FindDepVars(TreePatternNode *N, MultipleUseVarSet &DepVars) {
+  DepVarMap depcounts;
+  FindDepVarsOf(N, depcounts);
+  for (DepVarMap_citer i = depcounts.begin(); i != depcounts.end(); ++i) {
+    if (i->second > 1) {            // std::pair<std::string, int>
+      DepVars.insert(i->first);
+    }
+  }
+}
+
+//! Dump the dependent variable set:
+void DumpDepVars(MultipleUseVarSet &DepVars) {
+  if (DepVars.empty()) {
+    DEBUG(errs() << "<empty set>");
+  } else {
+    DEBUG(errs() << "[ ");
+    for (MultipleUseVarSet::const_iterator i = DepVars.begin(), e = DepVars.end();
+         i != e; ++i) {
+      DEBUG(errs() << (*i) << " ");
+    }
+    DEBUG(errs() << "]");
+  }
+}
+}
+
+//===----------------------------------------------------------------------===//
+// PatternToMatch implementation
+//
+
+
+/// getPatternSize - Return the 'size' of this pattern.  We want to match large
+/// patterns before small ones.  This is used to determine the size of a
+/// pattern.
+static unsigned getPatternSize(const TreePatternNode *P,
+                               const CodeGenDAGPatterns &CGP) {
+  unsigned Size = 3;  // The node itself.
+  // If the root node is a ConstantSDNode, increases its size.
+  // e.g. (set R32:$dst, 0).
+  if (P->isLeaf() && dynamic_cast<IntInit*>(P->getLeafValue()))
+    Size += 2;
+  
+  // FIXME: This is a hack to statically increase the priority of patterns
+  // which maps a sub-dag to a complex pattern. e.g. favors LEA over ADD.
+  // Later we can allow complexity / cost for each pattern to be (optionally)
+  // specified. To get best possible pattern match we'll need to dynamically
+  // calculate the complexity of all patterns a dag can potentially map to.
+  const ComplexPattern *AM = P->getComplexPatternInfo(CGP);
+  if (AM)
+    Size += AM->getNumOperands() * 3;
+  
+  // If this node has some predicate function that must match, it adds to the
+  // complexity of this node.
+  if (!P->getPredicateFns().empty())
+    ++Size;
+  
+  // Count children in the count if they are also nodes.
+  for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i) {
+    TreePatternNode *Child = P->getChild(i);
+    if (!Child->isLeaf() && Child->getNumTypes() &&
+        Child->getType(0) != MVT::Other)
+      Size += getPatternSize(Child, CGP);
+    else if (Child->isLeaf()) {
+      if (dynamic_cast<IntInit*>(Child->getLeafValue())) 
+        Size += 5;  // Matches a ConstantSDNode (+3) and a specific value (+2).
+      else if (Child->getComplexPatternInfo(CGP))
+        Size += getPatternSize(Child, CGP);
+      else if (!Child->getPredicateFns().empty())
+        ++Size;
+    }
+  }
+  
+  return Size;
+}
+
+/// Compute the complexity metric for the input pattern.  This roughly
+/// corresponds to the number of nodes that are covered.
+unsigned PatternToMatch::
+getPatternComplexity(const CodeGenDAGPatterns &CGP) const {
+  return getPatternSize(getSrcPattern(), CGP) + getAddedComplexity();
+}
+
+
+/// getPredicateCheck - Return a single string containing all of this
+/// pattern's predicates concatenated with "&&" operators.
+///
+std::string PatternToMatch::getPredicateCheck() const {
+  std::string PredicateCheck;
+  for (unsigned i = 0, e = Predicates->getSize(); i != e; ++i) {
+    if (DefInit *Pred = dynamic_cast<DefInit*>(Predicates->getElement(i))) {
+      Record *Def = Pred->getDef();
+      if (!Def->isSubClassOf("Predicate")) {
+#ifndef NDEBUG
+        Def->dump();
+#endif
+        assert(0 && "Unknown predicate type!");
+      }
+      if (!PredicateCheck.empty())
+        PredicateCheck += " && ";
+      PredicateCheck += "(" + Def->getValueAsString("CondString") + ")";
+    }
+  }
+
+  return PredicateCheck;
+}
+
+//===----------------------------------------------------------------------===//
+// SDTypeConstraint implementation
+//
+
+SDTypeConstraint::SDTypeConstraint(Record *R) {
+  OperandNo = R->getValueAsInt("OperandNum");
+  
+  if (R->isSubClassOf("SDTCisVT")) {
+    ConstraintType = SDTCisVT;
+    x.SDTCisVT_Info.VT = getValueType(R->getValueAsDef("VT"));
+    if (x.SDTCisVT_Info.VT == MVT::isVoid)
+      throw TGError(R->getLoc(), "Cannot use 'Void' as type to SDTCisVT");
+      
+  } else if (R->isSubClassOf("SDTCisPtrTy")) {
+    ConstraintType = SDTCisPtrTy;
+  } else if (R->isSubClassOf("SDTCisInt")) {
+    ConstraintType = SDTCisInt;
+  } else if (R->isSubClassOf("SDTCisFP")) {
+    ConstraintType = SDTCisFP;
+  } else if (R->isSubClassOf("SDTCisVec")) {
+    ConstraintType = SDTCisVec;
+  } else if (R->isSubClassOf("SDTCisSameAs")) {
+    ConstraintType = SDTCisSameAs;
+    x.SDTCisSameAs_Info.OtherOperandNum = R->getValueAsInt("OtherOperandNum");
+  } else if (R->isSubClassOf("SDTCisVTSmallerThanOp")) {
+    ConstraintType = SDTCisVTSmallerThanOp;
+    x.SDTCisVTSmallerThanOp_Info.OtherOperandNum = 
+      R->getValueAsInt("OtherOperandNum");
+  } else if (R->isSubClassOf("SDTCisOpSmallerThanOp")) {
+    ConstraintType = SDTCisOpSmallerThanOp;
+    x.SDTCisOpSmallerThanOp_Info.BigOperandNum = 
+      R->getValueAsInt("BigOperandNum");
+  } else if (R->isSubClassOf("SDTCisEltOfVec")) {
+    ConstraintType = SDTCisEltOfVec;
+    x.SDTCisEltOfVec_Info.OtherOperandNum = R->getValueAsInt("OtherOpNum");
+  } else {
+    errs() << "Unrecognized SDTypeConstraint '" << R->getName() << "'!\n";
+    exit(1);
+  }
+}
+
+/// getOperandNum - Return the node corresponding to operand #OpNo in tree
+/// N, and the result number in ResNo.
+static TreePatternNode *getOperandNum(unsigned OpNo, TreePatternNode *N,
+                                      const SDNodeInfo &NodeInfo,
+                                      unsigned &ResNo) {
+  unsigned NumResults = NodeInfo.getNumResults();
+  if (OpNo < NumResults) {
+    ResNo = OpNo;
+    return N;
+  }
+  
+  OpNo -= NumResults;
+  
+  if (OpNo >= N->getNumChildren()) {
+    errs() << "Invalid operand number in type constraint " 
+           << (OpNo+NumResults) << " ";
+    N->dump();
+    errs() << '\n';
+    exit(1);
+  }
+
+  return N->getChild(OpNo);
+}
+
+/// ApplyTypeConstraint - Given a node in a pattern, apply this type
+/// constraint to the nodes operands.  This returns true if it makes a
+/// change, false otherwise.  If a type contradiction is found, throw an
+/// exception.
+bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N,
+                                           const SDNodeInfo &NodeInfo,
+                                           TreePattern &TP) const {
+  unsigned ResNo = 0; // The result number being referenced.
+  TreePatternNode *NodeToApply = getOperandNum(OperandNo, N, NodeInfo, ResNo);
+  
+  switch (ConstraintType) {
+  default: assert(0 && "Unknown constraint type!");
+  case SDTCisVT:
+    // Operand must be a particular type.
+    return NodeToApply->UpdateNodeType(ResNo, x.SDTCisVT_Info.VT, TP);
+  case SDTCisPtrTy:
+    // Operand must be same as target pointer type.
+    return NodeToApply->UpdateNodeType(ResNo, MVT::iPTR, TP);
+  case SDTCisInt:
+    // Require it to be one of the legal integer VTs.
+    return NodeToApply->getExtType(ResNo).EnforceInteger(TP);
+  case SDTCisFP:
+    // Require it to be one of the legal fp VTs.
+    return NodeToApply->getExtType(ResNo).EnforceFloatingPoint(TP);
+  case SDTCisVec:
+    // Require it to be one of the legal vector VTs.
+    return NodeToApply->getExtType(ResNo).EnforceVector(TP);
+  case SDTCisSameAs: {
+    unsigned OResNo = 0;
+    TreePatternNode *OtherNode =
+      getOperandNum(x.SDTCisSameAs_Info.OtherOperandNum, N, NodeInfo, OResNo);
+    return NodeToApply->UpdateNodeType(OResNo, OtherNode->getExtType(ResNo),TP)|
+           OtherNode->UpdateNodeType(ResNo,NodeToApply->getExtType(OResNo),TP);
+  }
+  case SDTCisVTSmallerThanOp: {
+    // The NodeToApply must be a leaf node that is a VT.  OtherOperandNum must
+    // have an integer type that is smaller than the VT.
+    if (!NodeToApply->isLeaf() ||
+        !dynamic_cast<DefInit*>(NodeToApply->getLeafValue()) ||
+        !static_cast<DefInit*>(NodeToApply->getLeafValue())->getDef()
+               ->isSubClassOf("ValueType"))
+      TP.error(N->getOperator()->getName() + " expects a VT operand!");
+    MVT::SimpleValueType VT =
+     getValueType(static_cast<DefInit*>(NodeToApply->getLeafValue())->getDef());
+    
+    EEVT::TypeSet TypeListTmp(VT, TP);
+    
+    unsigned OResNo = 0;
+    TreePatternNode *OtherNode =
+      getOperandNum(x.SDTCisVTSmallerThanOp_Info.OtherOperandNum, N, NodeInfo,
+                    OResNo);
+
+    return TypeListTmp.EnforceSmallerThan(OtherNode->getExtType(OResNo), TP);
+  }
+  case SDTCisOpSmallerThanOp: {
+    unsigned BResNo = 0;
+    TreePatternNode *BigOperand =
+      getOperandNum(x.SDTCisOpSmallerThanOp_Info.BigOperandNum, N, NodeInfo,
+                    BResNo);
+    return NodeToApply->getExtType(ResNo).
+                  EnforceSmallerThan(BigOperand->getExtType(BResNo), TP);
+  }
+  case SDTCisEltOfVec: {
+    unsigned VResNo = 0;
+    TreePatternNode *VecOperand =
+      getOperandNum(x.SDTCisEltOfVec_Info.OtherOperandNum, N, NodeInfo,
+                    VResNo);
+    
+    // Filter vector types out of VecOperand that don't have the right element
+    // type.
+    return VecOperand->getExtType(VResNo).
+      EnforceVectorEltTypeIs(NodeToApply->getExtType(ResNo), TP);
+  }
+  }  
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// SDNodeInfo implementation
+//
+SDNodeInfo::SDNodeInfo(Record *R) : Def(R) {
+  EnumName    = R->getValueAsString("Opcode");
+  SDClassName = R->getValueAsString("SDClass");
+  Record *TypeProfile = R->getValueAsDef("TypeProfile");
+  NumResults = TypeProfile->getValueAsInt("NumResults");
+  NumOperands = TypeProfile->getValueAsInt("NumOperands");
+  
+  // Parse the properties.
+  Properties = 0;
+  std::vector<Record*> PropList = R->getValueAsListOfDefs("Properties");
+  for (unsigned i = 0, e = PropList.size(); i != e; ++i) {
+    if (PropList[i]->getName() == "SDNPCommutative") {
+      Properties |= 1 << SDNPCommutative;
+    } else if (PropList[i]->getName() == "SDNPAssociative") {
+      Properties |= 1 << SDNPAssociative;
+    } else if (PropList[i]->getName() == "SDNPHasChain") {
+      Properties |= 1 << SDNPHasChain;
+    } else if (PropList[i]->getName() == "SDNPOutFlag") {
+      Properties |= 1 << SDNPOutFlag;
+    } else if (PropList[i]->getName() == "SDNPInFlag") {
+      Properties |= 1 << SDNPInFlag;
+    } else if (PropList[i]->getName() == "SDNPOptInFlag") {
+      Properties |= 1 << SDNPOptInFlag;
+    } else if (PropList[i]->getName() == "SDNPMayStore") {
+      Properties |= 1 << SDNPMayStore;
+    } else if (PropList[i]->getName() == "SDNPMayLoad") {
+      Properties |= 1 << SDNPMayLoad;
+    } else if (PropList[i]->getName() == "SDNPSideEffect") {
+      Properties |= 1 << SDNPSideEffect;
+    } else if (PropList[i]->getName() == "SDNPMemOperand") {
+      Properties |= 1 << SDNPMemOperand;
+    } else if (PropList[i]->getName() == "SDNPVariadic") {
+      Properties |= 1 << SDNPVariadic;
+    } else {
+      errs() << "Unknown SD Node property '" << PropList[i]->getName()
+             << "' on node '" << R->getName() << "'!\n";
+      exit(1);
+    }
+  }
+  
+  
+  // Parse the type constraints.
+  std::vector<Record*> ConstraintList =
+    TypeProfile->getValueAsListOfDefs("Constraints");
+  TypeConstraints.assign(ConstraintList.begin(), ConstraintList.end());
+}
+
+/// getKnownType - If the type constraints on this node imply a fixed type
+/// (e.g. all stores return void, etc), then return it as an
+/// MVT::SimpleValueType.  Otherwise, return EEVT::Other.
+MVT::SimpleValueType SDNodeInfo::getKnownType(unsigned ResNo) const {
+  unsigned NumResults = getNumResults();
+  assert(NumResults <= 1 &&
+         "We only work with nodes with zero or one result so far!");
+  assert(ResNo == 0 && "Only handles single result nodes so far");
+  
+  for (unsigned i = 0, e = TypeConstraints.size(); i != e; ++i) {
+    // Make sure that this applies to the correct node result.
+    if (TypeConstraints[i].OperandNo >= NumResults)  // FIXME: need value #
+      continue;
+    
+    switch (TypeConstraints[i].ConstraintType) {
+    default: break;
+    case SDTypeConstraint::SDTCisVT:
+      return TypeConstraints[i].x.SDTCisVT_Info.VT;
+    case SDTypeConstraint::SDTCisPtrTy:
+      return MVT::iPTR;
+    }
+  }
+  return MVT::Other;
+}
+
+//===----------------------------------------------------------------------===//
+// TreePatternNode implementation
+//
+
+TreePatternNode::~TreePatternNode() {
+#if 0 // FIXME: implement refcounted tree nodes!
+  for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+    delete getChild(i);
+#endif
+}
+
+static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) {
+  if (Operator->getName() == "set" ||
+      Operator->getName() == "implicit")
+    return 0;  // All return nothing.
+  
+  if (Operator->isSubClassOf("Intrinsic"))
+    return CDP.getIntrinsic(Operator).IS.RetVTs.size();
+  
+  if (Operator->isSubClassOf("SDNode"))
+    return CDP.getSDNodeInfo(Operator).getNumResults();
+  
+  if (Operator->isSubClassOf("PatFrag")) {
+    // If we've already parsed this pattern fragment, get it.  Otherwise, handle
+    // the forward reference case where one pattern fragment references another
+    // before it is processed.
+    if (TreePattern *PFRec = CDP.getPatternFragmentIfRead(Operator))
+      return PFRec->getOnlyTree()->getNumTypes();
+    
+    // Get the result tree.
+    DagInit *Tree = Operator->getValueAsDag("Fragment");
+    Record *Op = 0;
+    if (Tree && dynamic_cast<DefInit*>(Tree->getOperator()))
+      Op = dynamic_cast<DefInit*>(Tree->getOperator())->getDef();
+    assert(Op && "Invalid Fragment");
+    return GetNumNodeResults(Op, CDP);
+  }
+  
+  if (Operator->isSubClassOf("Instruction")) {
+    CodeGenInstruction &InstInfo = CDP.getTargetInfo().getInstruction(Operator);
+
+    // FIXME: Should allow access to all the results here.
+    unsigned NumDefsToAdd = InstInfo.NumDefs ? 1 : 0;
+    
+    // Add on one implicit def if it has a resolvable type.
+    if (InstInfo.HasOneImplicitDefWithKnownVT(CDP.getTargetInfo()) !=MVT::Other)
+      ++NumDefsToAdd;
+    return NumDefsToAdd;
+  }
+  
+  if (Operator->isSubClassOf("SDNodeXForm"))
+    return 1;  // FIXME: Generalize SDNodeXForm
+  
+  Operator->dump();
+  errs() << "Unhandled node in GetNumNodeResults\n";
+  exit(1);
+}
+
+void TreePatternNode::print(raw_ostream &OS) const {
+  if (isLeaf())
+    OS << *getLeafValue();
+  else
+    OS << '(' << getOperator()->getName();
+
+  for (unsigned i = 0, e = Types.size(); i != e; ++i)
+    OS << ':' << getExtType(i).getName();
+
+  if (!isLeaf()) {
+    if (getNumChildren() != 0) {
+      OS << " ";
+      getChild(0)->print(OS);
+      for (unsigned i = 1, e = getNumChildren(); i != e; ++i) {
+        OS << ", ";
+        getChild(i)->print(OS);
+      }
+    }
+    OS << ")";
+  }
+  
+  for (unsigned i = 0, e = PredicateFns.size(); i != e; ++i)
+    OS << "<<P:" << PredicateFns[i] << ">>";
+  if (TransformFn)
+    OS << "<<X:" << TransformFn->getName() << ">>";
+  if (!getName().empty())
+    OS << ":$" << getName();
+
+}
+void TreePatternNode::dump() const {
+  print(errs());
+}
+
+/// isIsomorphicTo - Return true if this node is recursively
+/// isomorphic to the specified node.  For this comparison, the node's
+/// entire state is considered. The assigned name is ignored, since
+/// nodes with differing names are considered isomorphic. However, if
+/// the assigned name is present in the dependent variable set, then
+/// the assigned name is considered significant and the node is
+/// isomorphic if the names match.
+bool TreePatternNode::isIsomorphicTo(const TreePatternNode *N,
+                                     const MultipleUseVarSet &DepVars) const {
+  if (N == this) return true;
+  if (N->isLeaf() != isLeaf() || getExtTypes() != N->getExtTypes() ||
+      getPredicateFns() != N->getPredicateFns() ||
+      getTransformFn() != N->getTransformFn())
+    return false;
+
+  if (isLeaf()) {
+    if (DefInit *DI = dynamic_cast<DefInit*>(getLeafValue())) {
+      if (DefInit *NDI = dynamic_cast<DefInit*>(N->getLeafValue())) {
+        return ((DI->getDef() == NDI->getDef())
+                && (DepVars.find(getName()) == DepVars.end()
+                    || getName() == N->getName()));
+      }
+    }
+    return getLeafValue() == N->getLeafValue();
+  }
+  
+  if (N->getOperator() != getOperator() ||
+      N->getNumChildren() != getNumChildren()) return false;
+  for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+    if (!getChild(i)->isIsomorphicTo(N->getChild(i), DepVars))
+      return false;
+  return true;
+}
+
+/// clone - Make a copy of this tree and all of its children.
+///
+TreePatternNode *TreePatternNode::clone() const {
+  TreePatternNode *New;
+  if (isLeaf()) {
+    New = new TreePatternNode(getLeafValue(), getNumTypes());
+  } else {
+    std::vector<TreePatternNode*> CChildren;
+    CChildren.reserve(Children.size());
+    for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+      CChildren.push_back(getChild(i)->clone());
+    New = new TreePatternNode(getOperator(), CChildren, getNumTypes());
+  }
+  New->setName(getName());
+  New->Types = Types;
+  New->setPredicateFns(getPredicateFns());
+  New->setTransformFn(getTransformFn());
+  return New;
+}
+
+/// RemoveAllTypes - Recursively strip all the types of this tree.
+void TreePatternNode::RemoveAllTypes() {
+  for (unsigned i = 0, e = Types.size(); i != e; ++i)
+    Types[i] = EEVT::TypeSet();  // Reset to unknown type.
+  if (isLeaf()) return;
+  for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+    getChild(i)->RemoveAllTypes();
+}
+
+
+/// SubstituteFormalArguments - Replace the formal arguments in this tree
+/// with actual values specified by ArgMap.
+void TreePatternNode::
+SubstituteFormalArguments(std::map<std::string, TreePatternNode*> &ArgMap) {
+  if (isLeaf()) return;
+  
+  for (unsigned i = 0, e = getNumChildren(); i != e; ++i) {
+    TreePatternNode *Child = getChild(i);
+    if (Child->isLeaf()) {
+      Init *Val = Child->getLeafValue();
+      if (dynamic_cast<DefInit*>(Val) &&
+          static_cast<DefInit*>(Val)->getDef()->getName() == "node") {
+        // We found a use of a formal argument, replace it with its value.
+        TreePatternNode *NewChild = ArgMap[Child->getName()];
+        assert(NewChild && "Couldn't find formal argument!");
+        assert((Child->getPredicateFns().empty() ||
+                NewChild->getPredicateFns() == Child->getPredicateFns()) &&
+               "Non-empty child predicate clobbered!");
+        setChild(i, NewChild);
+      }
+    } else {
+      getChild(i)->SubstituteFormalArguments(ArgMap);
+    }
+  }
+}
+
+
+/// InlinePatternFragments - If this pattern refers to any pattern
+/// fragments, inline them into place, giving us a pattern without any
+/// PatFrag references.
+TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) {
+  if (isLeaf()) return this;  // nothing to do.
+  Record *Op = getOperator();
+  
+  if (!Op->isSubClassOf("PatFrag")) {
+    // Just recursively inline children nodes.
+    for (unsigned i = 0, e = getNumChildren(); i != e; ++i) {
+      TreePatternNode *Child = getChild(i);
+      TreePatternNode *NewChild = Child->InlinePatternFragments(TP);
+
+      assert((Child->getPredicateFns().empty() ||
+              NewChild->getPredicateFns() == Child->getPredicateFns()) &&
+             "Non-empty child predicate clobbered!");
+
+      setChild(i, NewChild);
+    }
+    return this;
+  }
+
+  // Otherwise, we found a reference to a fragment.  First, look up its
+  // TreePattern record.
+  TreePattern *Frag = TP.getDAGPatterns().getPatternFragment(Op);
+  
+  // Verify that we are passing the right number of operands.
+  if (Frag->getNumArgs() != Children.size())
+    TP.error("'" + Op->getName() + "' fragment requires " +
+             utostr(Frag->getNumArgs()) + " operands!");
+
+  TreePatternNode *FragTree = Frag->getOnlyTree()->clone();
+
+  std::string Code = Op->getValueAsCode("Predicate");
+  if (!Code.empty())
+    FragTree->addPredicateFn("Predicate_"+Op->getName());
+
+  // Resolve formal arguments to their actual value.
+  if (Frag->getNumArgs()) {
+    // Compute the map of formal to actual arguments.
+    std::map<std::string, TreePatternNode*> ArgMap;
+    for (unsigned i = 0, e = Frag->getNumArgs(); i != e; ++i)
+      ArgMap[Frag->getArgName(i)] = getChild(i)->InlinePatternFragments(TP);
+  
+    FragTree->SubstituteFormalArguments(ArgMap);
+  }
+  
+  FragTree->setName(getName());
+  for (unsigned i = 0, e = Types.size(); i != e; ++i)
+    FragTree->UpdateNodeType(i, getExtType(i), TP);
+
+  // Transfer in the old predicates.
+  for (unsigned i = 0, e = getPredicateFns().size(); i != e; ++i)
+    FragTree->addPredicateFn(getPredicateFns()[i]);
+
+  // Get a new copy of this fragment to stitch into here.
+  //delete this;    // FIXME: implement refcounting!
+  
+  // The fragment we inlined could have recursive inlining that is needed.  See
+  // if there are any pattern fragments in it and inline them as needed.
+  return FragTree->InlinePatternFragments(TP);
+}
+
+/// getImplicitType - Check to see if the specified record has an implicit
+/// type which should be applied to it.  This will infer the type of register
+/// references from the register file information, for example.
+///
+static EEVT::TypeSet getImplicitType(Record *R, unsigned ResNo,
+                                     bool NotRegisters, TreePattern &TP) {
+  // Check to see if this is a register or a register class.
+  if (R->isSubClassOf("RegisterClass")) {
+    assert(ResNo == 0 && "Regclass ref only has one result!");
+    if (NotRegisters) 
+      return EEVT::TypeSet(); // Unknown.
+    const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo();
+    return EEVT::TypeSet(T.getRegisterClass(R).getValueTypes());
+  }
+  
+  if (R->isSubClassOf("PatFrag")) {
+    assert(ResNo == 0 && "FIXME: PatFrag with multiple results?");
+    // Pattern fragment types will be resolved when they are inlined.
+    return EEVT::TypeSet(); // Unknown.
+  }
+  
+  if (R->isSubClassOf("Register")) {
+    assert(ResNo == 0 && "Registers only produce one result!");
+    if (NotRegisters) 
+      return EEVT::TypeSet(); // Unknown.
+    const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo();
+    return EEVT::TypeSet(T.getRegisterVTs(R));
+  }
+
+  if (R->isSubClassOf("SubRegIndex")) {
+    assert(ResNo == 0 && "SubRegisterIndices only produce one result!");
+    return EEVT::TypeSet();
+  }
+  
+  if (R->isSubClassOf("ValueType") || R->isSubClassOf("CondCode")) {
+    assert(ResNo == 0 && "This node only has one result!");
+    // Using a VTSDNode or CondCodeSDNode.
+    return EEVT::TypeSet(MVT::Other, TP);
+  }
+  
+  if (R->isSubClassOf("ComplexPattern")) {
+    assert(ResNo == 0 && "FIXME: ComplexPattern with multiple results?");
+    if (NotRegisters) 
+      return EEVT::TypeSet(); // Unknown.
+   return EEVT::TypeSet(TP.getDAGPatterns().getComplexPattern(R).getValueType(),
+                         TP);
+  }
+  if (R->isSubClassOf("PointerLikeRegClass")) {
+    assert(ResNo == 0 && "Regclass can only have one result!");
+    return EEVT::TypeSet(MVT::iPTR, TP);
+  }
+  
+  if (R->getName() == "node" || R->getName() == "srcvalue" ||
+      R->getName() == "zero_reg") {
+    // Placeholder.
+    return EEVT::TypeSet(); // Unknown.
+  }
+  
+  TP.error("Unknown node flavor used in pattern: " + R->getName());
+  return EEVT::TypeSet(MVT::Other, TP);
+}
+
+
+/// getIntrinsicInfo - If this node corresponds to an intrinsic, return the
+/// CodeGenIntrinsic information for it, otherwise return a null pointer.
+const CodeGenIntrinsic *TreePatternNode::
+getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const {
+  if (getOperator() != CDP.get_intrinsic_void_sdnode() &&
+      getOperator() != CDP.get_intrinsic_w_chain_sdnode() &&
+      getOperator() != CDP.get_intrinsic_wo_chain_sdnode())
+    return 0;
+    
+  unsigned IID = 
+    dynamic_cast<IntInit*>(getChild(0)->getLeafValue())->getValue();
+  return &CDP.getIntrinsicInfo(IID);
+}
+
+/// getComplexPatternInfo - If this node corresponds to a ComplexPattern,
+/// return the ComplexPattern information, otherwise return null.
+const ComplexPattern *
+TreePatternNode::getComplexPatternInfo(const CodeGenDAGPatterns &CGP) const {
+  if (!isLeaf()) return 0;
+  
+  DefInit *DI = dynamic_cast<DefInit*>(getLeafValue());
+  if (DI && DI->getDef()->isSubClassOf("ComplexPattern"))
+    return &CGP.getComplexPattern(DI->getDef());
+  return 0;
+}
+
+/// NodeHasProperty - Return true if this node has the specified property.
+bool TreePatternNode::NodeHasProperty(SDNP Property,
+                                      const CodeGenDAGPatterns &CGP) const {
+  if (isLeaf()) {
+    if (const ComplexPattern *CP = getComplexPatternInfo(CGP))
+      return CP->hasProperty(Property);
+    return false;
+  }
+  
+  Record *Operator = getOperator();
+  if (!Operator->isSubClassOf("SDNode")) return false;
+  
+  return CGP.getSDNodeInfo(Operator).hasProperty(Property);
+}
+
+
+
+
+/// TreeHasProperty - Return true if any node in this tree has the specified
+/// property.
+bool TreePatternNode::TreeHasProperty(SDNP Property,
+                                      const CodeGenDAGPatterns &CGP) const {
+  if (NodeHasProperty(Property, CGP))
+    return true;
+  for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+    if (getChild(i)->TreeHasProperty(Property, CGP))
+      return true;
+  return false;
+}  
+
+/// isCommutativeIntrinsic - Return true if the node corresponds to a
+/// commutative intrinsic.
+bool
+TreePatternNode::isCommutativeIntrinsic(const CodeGenDAGPatterns &CDP) const {
+  if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP))
+    return Int->isCommutative;
+  return false;
+}
+
+
+/// ApplyTypeConstraints - Apply all of the type constraints relevant to
+/// this node and its children in the tree.  This returns true if it makes a
+/// change, false otherwise.  If a type contradiction is found, throw an
+/// exception.
+bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
+  CodeGenDAGPatterns &CDP = TP.getDAGPatterns();
+  if (isLeaf()) {
+    if (DefInit *DI = dynamic_cast<DefInit*>(getLeafValue())) {
+      // If it's a regclass or something else known, include the type.
+      bool MadeChange = false;
+      for (unsigned i = 0, e = Types.size(); i != e; ++i)
+        MadeChange |= UpdateNodeType(i, getImplicitType(DI->getDef(), i,
+                                                        NotRegisters, TP), TP);
+      return MadeChange;
+    }
+    
+    if (IntInit *II = dynamic_cast<IntInit*>(getLeafValue())) {
+      assert(Types.size() == 1 && "Invalid IntInit");
+      
+      // Int inits are always integers. :)
+      bool MadeChange = Types[0].EnforceInteger(TP);
+      
+      if (!Types[0].isConcrete())
+        return MadeChange;
+      
+      MVT::SimpleValueType VT = getType(0);
+      if (VT == MVT::iPTR || VT == MVT::iPTRAny)
+        return MadeChange;
+      
+      unsigned Size = EVT(VT).getSizeInBits();
+      // Make sure that the value is representable for this type.
+      if (Size >= 32) return MadeChange;
+      
+      int Val = (II->getValue() << (32-Size)) >> (32-Size);
+      if (Val == II->getValue()) return MadeChange;
+      
+      // If sign-extended doesn't fit, does it fit as unsigned?
+      unsigned ValueMask;
+      unsigned UnsignedVal;
+      ValueMask = unsigned(~uint32_t(0UL) >> (32-Size));
+      UnsignedVal = unsigned(II->getValue());
+
+      if ((ValueMask & UnsignedVal) == UnsignedVal)
+        return MadeChange;
+      
+      TP.error("Integer value '" + itostr(II->getValue())+
+               "' is out of range for type '" + getEnumName(getType(0)) + "'!");
+      return MadeChange;
+    }
+    return false;
+  }
+  
+  // special handling for set, which isn't really an SDNode.
+  if (getOperator()->getName() == "set") {
+    assert(getNumTypes() == 0 && "Set doesn't produce a value");
+    assert(getNumChildren() >= 2 && "Missing RHS of a set?");
+    unsigned NC = getNumChildren();
+    
+    TreePatternNode *SetVal = getChild(NC-1);
+    bool MadeChange = SetVal->ApplyTypeConstraints(TP, NotRegisters);
+
+    for (unsigned i = 0; i < NC-1; ++i) {
+      TreePatternNode *Child = getChild(i);
+      MadeChange |= Child->ApplyTypeConstraints(TP, NotRegisters);
+    
+      // Types of operands must match.
+      MadeChange |= Child->UpdateNodeType(0, SetVal->getExtType(i), TP);
+      MadeChange |= SetVal->UpdateNodeType(i, Child->getExtType(0), TP);
+    }
+    return MadeChange;
+  }
+  
+  if (getOperator()->getName() == "implicit") {
+    assert(getNumTypes() == 0 && "Node doesn't produce a value");
+
+    bool MadeChange = false;
+    for (unsigned i = 0; i < getNumChildren(); ++i)
+      MadeChange = getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
+    return MadeChange;
+  }
+  
+  if (getOperator()->getName() == "COPY_TO_REGCLASS") {
+    bool MadeChange = false;
+    MadeChange |= getChild(0)->ApplyTypeConstraints(TP, NotRegisters);
+    MadeChange |= getChild(1)->ApplyTypeConstraints(TP, NotRegisters);
+    
+    assert(getChild(0)->getNumTypes() == 1 &&
+           getChild(1)->getNumTypes() == 1 && "Unhandled case");
+    
+    // child #1 of COPY_TO_REGCLASS should be a register class.  We don't care
+    // what type it gets, so if it didn't get a concrete type just give it the
+    // first viable type from the reg class.
+    if (!getChild(1)->hasTypeSet(0) &&
+        !getChild(1)->getExtType(0).isCompletelyUnknown()) {
+      MVT::SimpleValueType RCVT = getChild(1)->getExtType(0).getTypeList()[0];
+      MadeChange |= getChild(1)->UpdateNodeType(0, RCVT, TP);
+    }
+    return MadeChange;
+  }
+  
+  if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP)) {
+    bool MadeChange = false;
+
+    // Apply the result type to the node.
+    unsigned NumRetVTs = Int->IS.RetVTs.size();
+    unsigned NumParamVTs = Int->IS.ParamVTs.size();
+    
+    for (unsigned i = 0, e = NumRetVTs; i != e; ++i)
+      MadeChange |= UpdateNodeType(i, Int->IS.RetVTs[i], TP);
+
+    if (getNumChildren() != NumParamVTs + 1)
+      TP.error("Intrinsic '" + Int->Name + "' expects " +
+               utostr(NumParamVTs) + " operands, not " +
+               utostr(getNumChildren() - 1) + " operands!");
+
+    // Apply type info to the intrinsic ID.
+    MadeChange |= getChild(0)->UpdateNodeType(0, MVT::iPTR, TP);
+    
+    for (unsigned i = 0, e = getNumChildren()-1; i != e; ++i) {
+      MadeChange |= getChild(i+1)->ApplyTypeConstraints(TP, NotRegisters);
+      
+      MVT::SimpleValueType OpVT = Int->IS.ParamVTs[i];
+      assert(getChild(i+1)->getNumTypes() == 1 && "Unhandled case");
+      MadeChange |= getChild(i+1)->UpdateNodeType(0, OpVT, TP);
+    }
+    return MadeChange;
+  }
+  
+  if (getOperator()->isSubClassOf("SDNode")) {
+    const SDNodeInfo &NI = CDP.getSDNodeInfo(getOperator());
+    
+    // Check that the number of operands is sane.  Negative operands -> varargs.
+    if (NI.getNumOperands() >= 0 &&
+        getNumChildren() != (unsigned)NI.getNumOperands())
+      TP.error(getOperator()->getName() + " node requires exactly " +
+               itostr(NI.getNumOperands()) + " operands!");
+    
+    bool MadeChange = NI.ApplyTypeConstraints(this, TP);
+    for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+      MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
+    return MadeChange;
+  }
+  
+  if (getOperator()->isSubClassOf("Instruction")) {
+    const DAGInstruction &Inst = CDP.getInstruction(getOperator());
+    CodeGenInstruction &InstInfo =
+      CDP.getTargetInfo().getInstruction(getOperator());
+    
+    bool MadeChange = false;
+
+    // Apply the result types to the node, these come from the things in the
+    // (outs) list of the instruction.
+    // FIXME: Cap at one result so far.
+    unsigned NumResultsToAdd = InstInfo.NumDefs ? 1 : 0;
+    for (unsigned ResNo = 0; ResNo != NumResultsToAdd; ++ResNo) {
+      Record *ResultNode = Inst.getResult(ResNo);
+      
+      if (ResultNode->isSubClassOf("PointerLikeRegClass")) {
+        MadeChange |= UpdateNodeType(ResNo, MVT::iPTR, TP);
+      } else if (ResultNode->getName() == "unknown") {
+        // Nothing to do.
+      } else {
+        assert(ResultNode->isSubClassOf("RegisterClass") &&
+               "Operands should be register classes!");
+        const CodeGenRegisterClass &RC = 
+          CDP.getTargetInfo().getRegisterClass(ResultNode);
+        MadeChange |= UpdateNodeType(ResNo, RC.getValueTypes(), TP);
+      }
+    }
+    
+    // If the instruction has implicit defs, we apply the first one as a result.
+    // FIXME: This sucks, it should apply all implicit defs.
+    if (!InstInfo.ImplicitDefs.empty()) {
+      unsigned ResNo = NumResultsToAdd;
+      
+      // FIXME: Generalize to multiple possible types and multiple possible
+      // ImplicitDefs.
+      MVT::SimpleValueType VT =
+        InstInfo.HasOneImplicitDefWithKnownVT(CDP.getTargetInfo());
+      
+      if (VT != MVT::Other)
+        MadeChange |= UpdateNodeType(ResNo, VT, TP);
+    }
+    
+    // If this is an INSERT_SUBREG, constrain the source and destination VTs to
+    // be the same.
+    if (getOperator()->getName() == "INSERT_SUBREG") {
+      assert(getChild(0)->getNumTypes() == 1 && "FIXME: Unhandled");
+      MadeChange |= UpdateNodeType(0, getChild(0)->getExtType(0), TP);
+      MadeChange |= getChild(0)->UpdateNodeType(0, getExtType(0), TP);
+    }
+
+    unsigned ChildNo = 0;
+    for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i) {
+      Record *OperandNode = Inst.getOperand(i);
+      
+      // If the instruction expects a predicate or optional def operand, we
+      // codegen this by setting the operand to it's default value if it has a
+      // non-empty DefaultOps field.
+      if ((OperandNode->isSubClassOf("PredicateOperand") ||
+           OperandNode->isSubClassOf("OptionalDefOperand")) &&
+          !CDP.getDefaultOperand(OperandNode).DefaultOps.empty())
+        continue;
+       
+      // Verify that we didn't run out of provided operands.
+      if (ChildNo >= getNumChildren())
+        TP.error("Instruction '" + getOperator()->getName() +
+                 "' expects more operands than were provided.");
+      
+      MVT::SimpleValueType VT;
+      TreePatternNode *Child = getChild(ChildNo++);
+      unsigned ChildResNo = 0;  // Instructions always use res #0 of their op.
+      
+      if (OperandNode->isSubClassOf("RegisterClass")) {
+        const CodeGenRegisterClass &RC = 
+          CDP.getTargetInfo().getRegisterClass(OperandNode);
+        MadeChange |= Child->UpdateNodeType(ChildResNo, RC.getValueTypes(), TP);
+      } else if (OperandNode->isSubClassOf("Operand")) {
+        VT = getValueType(OperandNode->getValueAsDef("Type"));
+        MadeChange |= Child->UpdateNodeType(ChildResNo, VT, TP);
+      } else if (OperandNode->isSubClassOf("PointerLikeRegClass")) {
+        MadeChange |= Child->UpdateNodeType(ChildResNo, MVT::iPTR, TP);
+      } else if (OperandNode->getName() == "unknown") {
+        // Nothing to do.
+      } else {
+        assert(0 && "Unknown operand type!");
+        abort();
+      }
+      MadeChange |= Child->ApplyTypeConstraints(TP, NotRegisters);
+    }
+
+    if (ChildNo != getNumChildren())
+      TP.error("Instruction '" + getOperator()->getName() +
+               "' was provided too many operands!");
+    
+    return MadeChange;
+  }
+  
+  assert(getOperator()->isSubClassOf("SDNodeXForm") && "Unknown node type!");
+  
+  // Node transforms always take one operand.
+  if (getNumChildren() != 1)
+    TP.error("Node transform '" + getOperator()->getName() +
+             "' requires one operand!");
+
+  bool MadeChange = getChild(0)->ApplyTypeConstraints(TP, NotRegisters);
+
+  
+  // If either the output or input of the xform does not have exact
+  // type info. We assume they must be the same. Otherwise, it is perfectly
+  // legal to transform from one type to a completely different type.
+#if 0
+  if (!hasTypeSet() || !getChild(0)->hasTypeSet()) {
+    bool MadeChange = UpdateNodeType(getChild(0)->getExtType(), TP);
+    MadeChange |= getChild(0)->UpdateNodeType(getExtType(), TP);
+    return MadeChange;
+  }
+#endif
+  return MadeChange;
+}
+
+/// OnlyOnRHSOfCommutative - Return true if this value is only allowed on the
+/// RHS of a commutative operation, not the on LHS.
+static bool OnlyOnRHSOfCommutative(TreePatternNode *N) {
+  if (!N->isLeaf() && N->getOperator()->getName() == "imm")
+    return true;
+  if (N->isLeaf() && dynamic_cast<IntInit*>(N->getLeafValue()))
+    return true;
+  return false;
+}
+
+
+/// canPatternMatch - If it is impossible for this pattern to match on this
+/// target, fill in Reason and return false.  Otherwise, return true.  This is
+/// used as a sanity check for .td files (to prevent people from writing stuff
+/// that can never possibly work), and to prevent the pattern permuter from
+/// generating stuff that is useless.
+bool TreePatternNode::canPatternMatch(std::string &Reason, 
+                                      const CodeGenDAGPatterns &CDP) {
+  if (isLeaf()) return true;
+
+  for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+    if (!getChild(i)->canPatternMatch(Reason, CDP))
+      return false;
+
+  // If this is an intrinsic, handle cases that would make it not match.  For
+  // example, if an operand is required to be an immediate.
+  if (getOperator()->isSubClassOf("Intrinsic")) {
+    // TODO:
+    return true;
+  }
+  
+  // If this node is a commutative operator, check that the LHS isn't an
+  // immediate.
+  const SDNodeInfo &NodeInfo = CDP.getSDNodeInfo(getOperator());
+  bool isCommIntrinsic = isCommutativeIntrinsic(CDP);
+  if (NodeInfo.hasProperty(SDNPCommutative) || isCommIntrinsic) {
+    // Scan all of the operands of the node and make sure that only the last one
+    // is a constant node, unless the RHS also is.
+    if (!OnlyOnRHSOfCommutative(getChild(getNumChildren()-1))) {
+      bool Skip = isCommIntrinsic ? 1 : 0; // First operand is intrinsic id.
+      for (unsigned i = Skip, e = getNumChildren()-1; i != e; ++i)
+        if (OnlyOnRHSOfCommutative(getChild(i))) {
+          Reason="Immediate value must be on the RHS of commutative operators!";
+          return false;
+        }
+    }
+  }
+  
+  return true;
+}
+
+//===----------------------------------------------------------------------===//
+// TreePattern implementation
+//
+
+TreePattern::TreePattern(Record *TheRec, ListInit *RawPat, bool isInput,
+                         CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp){
+  isInputPattern = isInput;
+  for (unsigned i = 0, e = RawPat->getSize(); i != e; ++i)
+    Trees.push_back(ParseTreePattern(RawPat->getElement(i), ""));
+}
+
+TreePattern::TreePattern(Record *TheRec, DagInit *Pat, bool isInput,
+                         CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp){
+  isInputPattern = isInput;
+  Trees.push_back(ParseTreePattern(Pat, ""));
+}
+
+TreePattern::TreePattern(Record *TheRec, TreePatternNode *Pat, bool isInput,
+                         CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp){
+  isInputPattern = isInput;
+  Trees.push_back(Pat);
+}
+
+void TreePattern::error(const std::string &Msg) const {
+  dump();
+  throw TGError(TheRecord->getLoc(), "In " + TheRecord->getName() + ": " + Msg);
+}
+
+void TreePattern::ComputeNamedNodes() {
+  for (unsigned i = 0, e = Trees.size(); i != e; ++i)
+    ComputeNamedNodes(Trees[i]);
+}
+
+void TreePattern::ComputeNamedNodes(TreePatternNode *N) {
+  if (!N->getName().empty())
+    NamedNodes[N->getName()].push_back(N);
+  
+  for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
+    ComputeNamedNodes(N->getChild(i));
+}
+
+
+TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){
+  if (DefInit *DI = dynamic_cast<DefInit*>(TheInit)) {
+    Record *R = DI->getDef();
+    
+    // Direct reference to a leaf DagNode or PatFrag?  Turn it into a
+    // TreePatternNode if its own.  For example:
+    ///   (foo GPR, imm) -> (foo GPR, (imm))
+    if (R->isSubClassOf("SDNode") || R->isSubClassOf("PatFrag"))
+      return ParseTreePattern(new DagInit(DI, "",
+                          std::vector<std::pair<Init*, std::string> >()),
+                              OpName);
+    
+    // Input argument?
+    TreePatternNode *Res = new TreePatternNode(DI, 1);
+    if (R->getName() == "node" && !OpName.empty()) {
+      if (OpName.empty())
+        error("'node' argument requires a name to match with operand list");
+      Args.push_back(OpName);
+    }
+
+    Res->setName(OpName);
+    return Res;
+  }
+  
+  if (IntInit *II = dynamic_cast<IntInit*>(TheInit)) {
+    if (!OpName.empty())
+      error("Constant int argument should not have a name!");
+    return new TreePatternNode(II, 1);
+  }
+  
+  if (BitsInit *BI = dynamic_cast<BitsInit*>(TheInit)) {
+    // Turn this into an IntInit.
+    Init *II = BI->convertInitializerTo(new IntRecTy());
+    if (II == 0 || !dynamic_cast<IntInit*>(II))
+      error("Bits value must be constants!");
+    return ParseTreePattern(II, OpName);
+  }
+
+  DagInit *Dag = dynamic_cast<DagInit*>(TheInit);
+  if (!Dag) {
+    TheInit->dump();
+    error("Pattern has unexpected init kind!");
+  }
+  DefInit *OpDef = dynamic_cast<DefInit*>(Dag->getOperator());
+  if (!OpDef) error("Pattern has unexpected operator type!");
+  Record *Operator = OpDef->getDef();
+  
+  if (Operator->isSubClassOf("ValueType")) {
+    // If the operator is a ValueType, then this must be "type cast" of a leaf
+    // node.
+    if (Dag->getNumArgs() != 1)
+      error("Type cast only takes one operand!");
+    
+    TreePatternNode *New = ParseTreePattern(Dag->getArg(0), Dag->getArgName(0));
+    
+    // Apply the type cast.
+    assert(New->getNumTypes() == 1 && "FIXME: Unhandled");
+    New->UpdateNodeType(0, getValueType(Operator), *this);
+    
+    if (!OpName.empty())
+      error("ValueType cast should not have a name!");
+    return New;
+  }
+  
+  // Verify that this is something that makes sense for an operator.
+  if (!Operator->isSubClassOf("PatFrag") && 
+      !Operator->isSubClassOf("SDNode") &&
+      !Operator->isSubClassOf("Instruction") && 
+      !Operator->isSubClassOf("SDNodeXForm") &&
+      !Operator->isSubClassOf("Intrinsic") &&
+      Operator->getName() != "set" &&
+      Operator->getName() != "implicit")
+    error("Unrecognized node '" + Operator->getName() + "'!");
+  
+  //  Check to see if this is something that is illegal in an input pattern.
+  if (isInputPattern) {
+    if (Operator->isSubClassOf("Instruction") ||
+        Operator->isSubClassOf("SDNodeXForm"))
+      error("Cannot use '" + Operator->getName() + "' in an input pattern!");
+  } else {
+    if (Operator->isSubClassOf("Intrinsic"))
+      error("Cannot use '" + Operator->getName() + "' in an output pattern!");
+    
+    if (Operator->isSubClassOf("SDNode") &&
+        Operator->getName() != "imm" &&
+        Operator->getName() != "fpimm" &&
+        Operator->getName() != "tglobaltlsaddr" &&
+        Operator->getName() != "tconstpool" &&
+        Operator->getName() != "tjumptable" &&
+        Operator->getName() != "tframeindex" &&
+        Operator->getName() != "texternalsym" &&
+        Operator->getName() != "tblockaddress" &&
+        Operator->getName() != "tglobaladdr" &&
+        Operator->getName() != "bb" &&
+        Operator->getName() != "vt")
+      error("Cannot use '" + Operator->getName() + "' in an output pattern!");
+  }
+  
+  std::vector<TreePatternNode*> Children;
+
+  // Parse all the operands.
+  for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i)
+    Children.push_back(ParseTreePattern(Dag->getArg(i), Dag->getArgName(i)));
+  
+  // If the operator is an intrinsic, then this is just syntactic sugar for for
+  // (intrinsic_* <number>, ..children..).  Pick the right intrinsic node, and 
+  // convert the intrinsic name to a number.
+  if (Operator->isSubClassOf("Intrinsic")) {
+    const CodeGenIntrinsic &Int = getDAGPatterns().getIntrinsic(Operator);
+    unsigned IID = getDAGPatterns().getIntrinsicID(Operator)+1;
+
+    // If this intrinsic returns void, it must have side-effects and thus a
+    // chain.
+    if (Int.IS.RetVTs.empty())
+      Operator = getDAGPatterns().get_intrinsic_void_sdnode();
+    else if (Int.ModRef != CodeGenIntrinsic::NoMem)
+      // Has side-effects, requires chain.
+      Operator = getDAGPatterns().get_intrinsic_w_chain_sdnode();
+    else // Otherwise, no chain.
+      Operator = getDAGPatterns().get_intrinsic_wo_chain_sdnode();
+    
+    TreePatternNode *IIDNode = new TreePatternNode(new IntInit(IID), 1);
+    Children.insert(Children.begin(), IIDNode);
+  }
+  
+  unsigned NumResults = GetNumNodeResults(Operator, CDP);
+  TreePatternNode *Result = new TreePatternNode(Operator, Children, NumResults);
+  Result->setName(OpName);
+  
+  if (!Dag->getName().empty()) {
+    assert(Result->getName().empty());
+    Result->setName(Dag->getName());
+  }
+  return Result;
+}
+
+/// SimplifyTree - See if we can simplify this tree to eliminate something that
+/// will never match in favor of something obvious that will.  This is here
+/// strictly as a convenience to target authors because it allows them to write
+/// more type generic things and have useless type casts fold away.
+///
+/// This returns true if any change is made.
+static bool SimplifyTree(TreePatternNode *&N) {
+  if (N->isLeaf())
+    return false;
+
+  // If we have a bitconvert with a resolved type and if the source and
+  // destination types are the same, then the bitconvert is useless, remove it.
+  if (N->getOperator()->getName() == "bitconvert" &&
+      N->getExtType(0).isConcrete() &&
+      N->getExtType(0) == N->getChild(0)->getExtType(0) &&
+      N->getName().empty()) {
+    N = N->getChild(0);
+    SimplifyTree(N);
+    return true;
+  }
+
+  // Walk all children.
+  bool MadeChange = false;
+  for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
+    TreePatternNode *Child = N->getChild(i);
+    MadeChange |= SimplifyTree(Child);
+    N->setChild(i, Child);
+  }
+  return MadeChange;
+}
+
+
+
+/// InferAllTypes - Infer/propagate as many types throughout the expression
+/// patterns as possible.  Return true if all types are inferred, false
+/// otherwise.  Throw an exception if a type contradiction is found.
+bool TreePattern::
+InferAllTypes(const StringMap<SmallVector<TreePatternNode*,1> > *InNamedTypes) {
+  if (NamedNodes.empty())
+    ComputeNamedNodes();
+
+  bool MadeChange = true;
+  while (MadeChange) {
+    MadeChange = false;
+    for (unsigned i = 0, e = Trees.size(); i != e; ++i) {
+      MadeChange |= Trees[i]->ApplyTypeConstraints(*this, false);
+      MadeChange |= SimplifyTree(Trees[i]);
+    }
+
+    // If there are constraints on our named nodes, apply them.
+    for (StringMap<SmallVector<TreePatternNode*,1> >::iterator 
+         I = NamedNodes.begin(), E = NamedNodes.end(); I != E; ++I) {
+      SmallVectorImpl<TreePatternNode*> &Nodes = I->second;
+      
+      // If we have input named node types, propagate their types to the named
+      // values here.
+      if (InNamedTypes) {
+        // FIXME: Should be error?
+        assert(InNamedTypes->count(I->getKey()) &&
+               "Named node in output pattern but not input pattern?");
+
+        const SmallVectorImpl<TreePatternNode*> &InNodes =
+          InNamedTypes->find(I->getKey())->second;
+
+        // The input types should be fully resolved by now.
+        for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
+          // If this node is a register class, and it is the root of the pattern
+          // then we're mapping something onto an input register.  We allow
+          // changing the type of the input register in this case.  This allows
+          // us to match things like:
+          //  def : Pat<(v1i64 (bitconvert(v2i32 DPR:$src))), (v1i64 DPR:$src)>;
+          if (Nodes[i] == Trees[0] && Nodes[i]->isLeaf()) {
+            DefInit *DI = dynamic_cast<DefInit*>(Nodes[i]->getLeafValue());
+            if (DI && DI->getDef()->isSubClassOf("RegisterClass"))
+              continue;
+          }
+          
+          assert(Nodes[i]->getNumTypes() == 1 &&
+                 InNodes[0]->getNumTypes() == 1 &&
+                 "FIXME: cannot name multiple result nodes yet");
+          MadeChange |= Nodes[i]->UpdateNodeType(0, InNodes[0]->getExtType(0),
+                                                 *this);
+        }
+      }
+      
+      // If there are multiple nodes with the same name, they must all have the
+      // same type.
+      if (I->second.size() > 1) {
+        for (unsigned i = 0, e = Nodes.size()-1; i != e; ++i) {
+          TreePatternNode *N1 = Nodes[i], *N2 = Nodes[i+1];
+          assert(N1->getNumTypes() == 1 && N2->getNumTypes() == 1 &&
+                 "FIXME: cannot name multiple result nodes yet");
+          
+          MadeChange |= N1->UpdateNodeType(0, N2->getExtType(0), *this);
+          MadeChange |= N2->UpdateNodeType(0, N1->getExtType(0), *this);
+        }
+      }
+    }
+  }
+  
+  bool HasUnresolvedTypes = false;
+  for (unsigned i = 0, e = Trees.size(); i != e; ++i)
+    HasUnresolvedTypes |= Trees[i]->ContainsUnresolvedType();
+  return !HasUnresolvedTypes;
+}
+
+void TreePattern::print(raw_ostream &OS) const {
+  OS << getRecord()->getName();
+  if (!Args.empty()) {
+    OS << "(" << Args[0];
+    for (unsigned i = 1, e = Args.size(); i != e; ++i)
+      OS << ", " << Args[i];
+    OS << ")";
+  }
+  OS << ": ";
+  
+  if (Trees.size() > 1)
+    OS << "[\n";
+  for (unsigned i = 0, e = Trees.size(); i != e; ++i) {
+    OS << "\t";
+    Trees[i]->print(OS);
+    OS << "\n";
+  }
+
+  if (Trees.size() > 1)
+    OS << "]\n";
+}
+
+void TreePattern::dump() const { print(errs()); }
+
+//===----------------------------------------------------------------------===//
+// CodeGenDAGPatterns implementation
+//
+
+CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) : Records(R) {
+  Intrinsics = LoadIntrinsics(Records, false);
+  TgtIntrinsics = LoadIntrinsics(Records, true);
+  ParseNodeInfo();
+  ParseNodeTransforms();
+  ParseComplexPatterns();
+  ParsePatternFragments();
+  ParseDefaultOperands();
+  ParseInstructions();
+  ParsePatterns();
+  
+  // Generate variants.  For example, commutative patterns can match
+  // multiple ways.  Add them to PatternsToMatch as well.
+  GenerateVariants();
+
+  // Infer instruction flags.  For example, we can detect loads,
+  // stores, and side effects in many cases by examining an
+  // instruction's pattern.
+  InferInstructionFlags();
+}
+
+CodeGenDAGPatterns::~CodeGenDAGPatterns() {
+  for (pf_iterator I = PatternFragments.begin(),
+       E = PatternFragments.end(); I != E; ++I)
+    delete I->second;
+}
+
+
+Record *CodeGenDAGPatterns::getSDNodeNamed(const std::string &Name) const {
+  Record *N = Records.getDef(Name);
+  if (!N || !N->isSubClassOf("SDNode")) {
+    errs() << "Error getting SDNode '" << Name << "'!\n";
+    exit(1);
+  }
+  return N;
+}
+
+// Parse all of the SDNode definitions for the target, populating SDNodes.
+void CodeGenDAGPatterns::ParseNodeInfo() {
+  std::vector<Record*> Nodes = Records.getAllDerivedDefinitions("SDNode");
+  while (!Nodes.empty()) {
+    SDNodes.insert(std::make_pair(Nodes.back(), Nodes.back()));
+    Nodes.pop_back();
+  }
+
+  // Get the builtin intrinsic nodes.
+  intrinsic_void_sdnode     = getSDNodeNamed("intrinsic_void");
+  intrinsic_w_chain_sdnode  = getSDNodeNamed("intrinsic_w_chain");
+  intrinsic_wo_chain_sdnode = getSDNodeNamed("intrinsic_wo_chain");
+}
+
+/// ParseNodeTransforms - Parse all SDNodeXForm instances into the SDNodeXForms
+/// map, and emit them to the file as functions.
+void CodeGenDAGPatterns::ParseNodeTransforms() {
+  std::vector<Record*> Xforms = Records.getAllDerivedDefinitions("SDNodeXForm");
+  while (!Xforms.empty()) {
+    Record *XFormNode = Xforms.back();
+    Record *SDNode = XFormNode->getValueAsDef("Opcode");
+    std::string Code = XFormNode->getValueAsCode("XFormFunction");
+    SDNodeXForms.insert(std::make_pair(XFormNode, NodeXForm(SDNode, Code)));
+
+    Xforms.pop_back();
+  }
+}
+
+void CodeGenDAGPatterns::ParseComplexPatterns() {
+  std::vector<Record*> AMs = Records.getAllDerivedDefinitions("ComplexPattern");
+  while (!AMs.empty()) {
+    ComplexPatterns.insert(std::make_pair(AMs.back(), AMs.back()));
+    AMs.pop_back();
+  }
+}
+
+
+/// ParsePatternFragments - Parse all of the PatFrag definitions in the .td
+/// file, building up the PatternFragments map.  After we've collected them all,
+/// inline fragments together as necessary, so that there are no references left
+/// inside a pattern fragment to a pattern fragment.
+///
+void CodeGenDAGPatterns::ParsePatternFragments() {
+  std::vector<Record*> Fragments = Records.getAllDerivedDefinitions("PatFrag");
+  
+  // First step, parse all of the fragments.
+  for (unsigned i = 0, e = Fragments.size(); i != e; ++i) {
+    DagInit *Tree = Fragments[i]->getValueAsDag("Fragment");
+    TreePattern *P = new TreePattern(Fragments[i], Tree, true, *this);
+    PatternFragments[Fragments[i]] = P;
+    
+    // Validate the argument list, converting it to set, to discard duplicates.
+    std::vector<std::string> &Args = P->getArgList();
+    std::set<std::string> OperandsSet(Args.begin(), Args.end());
+    
+    if (OperandsSet.count(""))
+      P->error("Cannot have unnamed 'node' values in pattern fragment!");
+    
+    // Parse the operands list.
+    DagInit *OpsList = Fragments[i]->getValueAsDag("Operands");
+    DefInit *OpsOp = dynamic_cast<DefInit*>(OpsList->getOperator());
+    // Special cases: ops == outs == ins. Different names are used to
+    // improve readability.
+    if (!OpsOp ||
+        (OpsOp->getDef()->getName() != "ops" &&
+         OpsOp->getDef()->getName() != "outs" &&
+         OpsOp->getDef()->getName() != "ins"))
+      P->error("Operands list should start with '(ops ... '!");
+    
+    // Copy over the arguments.       
+    Args.clear();
+    for (unsigned j = 0, e = OpsList->getNumArgs(); j != e; ++j) {
+      if (!dynamic_cast<DefInit*>(OpsList->getArg(j)) ||
+          static_cast<DefInit*>(OpsList->getArg(j))->
+          getDef()->getName() != "node")
+        P->error("Operands list should all be 'node' values.");
+      if (OpsList->getArgName(j).empty())
+        P->error("Operands list should have names for each operand!");
+      if (!OperandsSet.count(OpsList->getArgName(j)))
+        P->error("'" + OpsList->getArgName(j) +
+                 "' does not occur in pattern or was multiply specified!");
+      OperandsSet.erase(OpsList->getArgName(j));
+      Args.push_back(OpsList->getArgName(j));
+    }
+    
+    if (!OperandsSet.empty())
+      P->error("Operands list does not contain an entry for operand '" +
+               *OperandsSet.begin() + "'!");
+
+    // If there is a code init for this fragment, keep track of the fact that
+    // this fragment uses it.
+    std::string Code = Fragments[i]->getValueAsCode("Predicate");
+    if (!Code.empty())
+      P->getOnlyTree()->addPredicateFn("Predicate_"+Fragments[i]->getName());
+    
+    // If there is a node transformation corresponding to this, keep track of
+    // it.
+    Record *Transform = Fragments[i]->getValueAsDef("OperandTransform");
+    if (!getSDNodeTransform(Transform).second.empty())    // not noop xform?
+      P->getOnlyTree()->setTransformFn(Transform);
+  }
+  
+  // Now that we've parsed all of the tree fragments, do a closure on them so
+  // that there are not references to PatFrags left inside of them.
+  for (unsigned i = 0, e = Fragments.size(); i != e; ++i) {
+    TreePattern *ThePat = PatternFragments[Fragments[i]];
+    ThePat->InlinePatternFragments();
+        
+    // Infer as many types as possible.  Don't worry about it if we don't infer
+    // all of them, some may depend on the inputs of the pattern.
+    try {
+      ThePat->InferAllTypes();
+    } catch (...) {
+      // If this pattern fragment is not supported by this target (no types can
+      // satisfy its constraints), just ignore it.  If the bogus pattern is
+      // actually used by instructions, the type consistency error will be
+      // reported there.
+    }
+    
+    // If debugging, print out the pattern fragment result.
+    DEBUG(ThePat->dump());
+  }
+}
+
+void CodeGenDAGPatterns::ParseDefaultOperands() {
+  std::vector<Record*> DefaultOps[2];
+  DefaultOps[0] = Records.getAllDerivedDefinitions("PredicateOperand");
+  DefaultOps[1] = Records.getAllDerivedDefinitions("OptionalDefOperand");
+
+  // Find some SDNode.
+  assert(!SDNodes.empty() && "No SDNodes parsed?");
+  Init *SomeSDNode = new DefInit(SDNodes.begin()->first);
+  
+  for (unsigned iter = 0; iter != 2; ++iter) {
+    for (unsigned i = 0, e = DefaultOps[iter].size(); i != e; ++i) {
+      DagInit *DefaultInfo = DefaultOps[iter][i]->getValueAsDag("DefaultOps");
+    
+      // Clone the DefaultInfo dag node, changing the operator from 'ops' to
+      // SomeSDnode so that we can parse this.
+      std::vector<std::pair<Init*, std::string> > Ops;
+      for (unsigned op = 0, e = DefaultInfo->getNumArgs(); op != e; ++op)
+        Ops.push_back(std::make_pair(DefaultInfo->getArg(op),
+                                     DefaultInfo->getArgName(op)));
+      DagInit *DI = new DagInit(SomeSDNode, "", Ops);
+    
+      // Create a TreePattern to parse this.
+      TreePattern P(DefaultOps[iter][i], DI, false, *this);
+      assert(P.getNumTrees() == 1 && "This ctor can only produce one tree!");
+
+      // Copy the operands over into a DAGDefaultOperand.
+      DAGDefaultOperand DefaultOpInfo;
+    
+      TreePatternNode *T = P.getTree(0);
+      for (unsigned op = 0, e = T->getNumChildren(); op != e; ++op) {
+        TreePatternNode *TPN = T->getChild(op);
+        while (TPN->ApplyTypeConstraints(P, false))
+          /* Resolve all types */;
+      
+        if (TPN->ContainsUnresolvedType()) {
+          if (iter == 0)
+            throw "Value #" + utostr(i) + " of PredicateOperand '" +
+              DefaultOps[iter][i]->getName() +"' doesn't have a concrete type!";
+          else
+            throw "Value #" + utostr(i) + " of OptionalDefOperand '" +
+              DefaultOps[iter][i]->getName() +"' doesn't have a concrete type!";
+        }
+        DefaultOpInfo.DefaultOps.push_back(TPN);
+      }
+
+      // Insert it into the DefaultOperands map so we can find it later.
+      DefaultOperands[DefaultOps[iter][i]] = DefaultOpInfo;
+    }
+  }
+}
+
+/// HandleUse - Given "Pat" a leaf in the pattern, check to see if it is an
+/// instruction input.  Return true if this is a real use.
+static bool HandleUse(TreePattern *I, TreePatternNode *Pat,
+                      std::map<std::string, TreePatternNode*> &InstInputs) {
+  // No name -> not interesting.
+  if (Pat->getName().empty()) {
+    if (Pat->isLeaf()) {
+      DefInit *DI = dynamic_cast<DefInit*>(Pat->getLeafValue());
+      if (DI && DI->getDef()->isSubClassOf("RegisterClass"))
+        I->error("Input " + DI->getDef()->getName() + " must be named!");
+    }
+    return false;
+  }
+
+  Record *Rec;
+  if (Pat->isLeaf()) {
+    DefInit *DI = dynamic_cast<DefInit*>(Pat->getLeafValue());
+    if (!DI) I->error("Input $" + Pat->getName() + " must be an identifier!");
+    Rec = DI->getDef();
+  } else {
+    Rec = Pat->getOperator();
+  }
+
+  // SRCVALUE nodes are ignored.
+  if (Rec->getName() == "srcvalue")
+    return false;
+
+  TreePatternNode *&Slot = InstInputs[Pat->getName()];
+  if (!Slot) {
+    Slot = Pat;
+    return true;
+  }
+  Record *SlotRec;
+  if (Slot->isLeaf()) {
+    SlotRec = dynamic_cast<DefInit*>(Slot->getLeafValue())->getDef();
+  } else {
+    assert(Slot->getNumChildren() == 0 && "can't be a use with children!");
+    SlotRec = Slot->getOperator();
+  }
+  
+  // Ensure that the inputs agree if we've already seen this input.
+  if (Rec != SlotRec)
+    I->error("All $" + Pat->getName() + " inputs must agree with each other");
+  if (Slot->getExtTypes() != Pat->getExtTypes())
+    I->error("All $" + Pat->getName() + " inputs must agree with each other");
+  return true;
+}
+
+/// FindPatternInputsAndOutputs - Scan the specified TreePatternNode (which is
+/// part of "I", the instruction), computing the set of inputs and outputs of
+/// the pattern.  Report errors if we see anything naughty.
+void CodeGenDAGPatterns::
+FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
+                            std::map<std::string, TreePatternNode*> &InstInputs,
+                            std::map<std::string, TreePatternNode*>&InstResults,
+                            std::vector<Record*> &InstImpResults) {
+  if (Pat->isLeaf()) {
+    bool isUse = HandleUse(I, Pat, InstInputs);
+    if (!isUse && Pat->getTransformFn())
+      I->error("Cannot specify a transform function for a non-input value!");
+    return;
+  }
+  
+  if (Pat->getOperator()->getName() == "implicit") {
+    for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) {
+      TreePatternNode *Dest = Pat->getChild(i);
+      if (!Dest->isLeaf())
+        I->error("implicitly defined value should be a register!");
+    
+      DefInit *Val = dynamic_cast<DefInit*>(Dest->getLeafValue());
+      if (!Val || !Val->getDef()->isSubClassOf("Register"))
+        I->error("implicitly defined value should be a register!");
+      InstImpResults.push_back(Val->getDef());
+    }
+    return;
+  }
+  
+  if (Pat->getOperator()->getName() != "set") {
+    // If this is not a set, verify that the children nodes are not void typed,
+    // and recurse.
+    for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) {
+      if (Pat->getChild(i)->getNumTypes() == 0)
+        I->error("Cannot have void nodes inside of patterns!");
+      FindPatternInputsAndOutputs(I, Pat->getChild(i), InstInputs, InstResults,
+                                  InstImpResults);
+    }
+    
+    // If this is a non-leaf node with no children, treat it basically as if
+    // it were a leaf.  This handles nodes like (imm).
+    bool isUse = HandleUse(I, Pat, InstInputs);
+    
+    if (!isUse && Pat->getTransformFn())
+      I->error("Cannot specify a transform function for a non-input value!");
+    return;
+  }
+  
+  // Otherwise, this is a set, validate and collect instruction results.
+  if (Pat->getNumChildren() == 0)
+    I->error("set requires operands!");
+  
+  if (Pat->getTransformFn())
+    I->error("Cannot specify a transform function on a set node!");
+  
+  // Check the set destinations.
+  unsigned NumDests = Pat->getNumChildren()-1;
+  for (unsigned i = 0; i != NumDests; ++i) {
+    TreePatternNode *Dest = Pat->getChild(i);
+    if (!Dest->isLeaf())
+      I->error("set destination should be a register!");
+    
+    DefInit *Val = dynamic_cast<DefInit*>(Dest->getLeafValue());
+    if (!Val)
+      I->error("set destination should be a register!");
+
+    if (Val->getDef()->isSubClassOf("RegisterClass") ||
+        Val->getDef()->isSubClassOf("PointerLikeRegClass")) {
+      if (Dest->getName().empty())
+        I->error("set destination must have a name!");
+      if (InstResults.count(Dest->getName()))
+        I->error("cannot set '" + Dest->getName() +"' multiple times");
+      InstResults[Dest->getName()] = Dest;
+    } else if (Val->getDef()->isSubClassOf("Register")) {
+      InstImpResults.push_back(Val->getDef());
+    } else {
+      I->error("set destination should be a register!");
+    }
+  }
+    
+  // Verify and collect info from the computation.
+  FindPatternInputsAndOutputs(I, Pat->getChild(NumDests),
+                              InstInputs, InstResults, InstImpResults);
+}
+
+//===----------------------------------------------------------------------===//
+// Instruction Analysis
+//===----------------------------------------------------------------------===//
+
+class InstAnalyzer {
+  const CodeGenDAGPatterns &CDP;
+  bool &mayStore;
+  bool &mayLoad;
+  bool &HasSideEffects;
+  bool &IsVariadic;
+public:
+  InstAnalyzer(const CodeGenDAGPatterns &cdp,
+               bool &maystore, bool &mayload, bool &hse, bool &isv)
+    : CDP(cdp), mayStore(maystore), mayLoad(mayload), HasSideEffects(hse),
+      IsVariadic(isv) {
+  }
+
+  /// Analyze - Analyze the specified instruction, returning true if the
+  /// instruction had a pattern.
+  bool Analyze(Record *InstRecord) {
+    const TreePattern *Pattern = CDP.getInstruction(InstRecord).getPattern();
+    if (Pattern == 0) {
+      HasSideEffects = 1;
+      return false;  // No pattern.
+    }
+
+    // FIXME: Assume only the first tree is the pattern. The others are clobber
+    // nodes.
+    AnalyzeNode(Pattern->getTree(0));
+    return true;
+  }
+
+private:
+  void AnalyzeNode(const TreePatternNode *N) {
+    if (N->isLeaf()) {
+      if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) {
+        Record *LeafRec = DI->getDef();
+        // Handle ComplexPattern leaves.
+        if (LeafRec->isSubClassOf("ComplexPattern")) {
+          const ComplexPattern &CP = CDP.getComplexPattern(LeafRec);
+          if (CP.hasProperty(SDNPMayStore)) mayStore = true;
+          if (CP.hasProperty(SDNPMayLoad)) mayLoad = true;
+          if (CP.hasProperty(SDNPSideEffect)) HasSideEffects = true;
+        }
+      }
+      return;
+    }
+
+    // Analyze children.
+    for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
+      AnalyzeNode(N->getChild(i));
+
+    // Ignore set nodes, which are not SDNodes.
+    if (N->getOperator()->getName() == "set")
+      return;
+
+    // Get information about the SDNode for the operator.
+    const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator());
+
+    // Notice properties of the node.
+    if (OpInfo.hasProperty(SDNPMayStore)) mayStore = true;
+    if (OpInfo.hasProperty(SDNPMayLoad)) mayLoad = true;
+    if (OpInfo.hasProperty(SDNPSideEffect)) HasSideEffects = true;
+    if (OpInfo.hasProperty(SDNPVariadic)) IsVariadic = true;
+
+    if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) {
+      // If this is an intrinsic, analyze it.
+      if (IntInfo->ModRef >= CodeGenIntrinsic::ReadArgMem)
+        mayLoad = true;// These may load memory.
+
+      if (IntInfo->ModRef >= CodeGenIntrinsic::ReadWriteArgMem)
+        mayStore = true;// Intrinsics that can write to memory are 'mayStore'.
+
+      if (IntInfo->ModRef >= CodeGenIntrinsic::ReadWriteMem)
+        // WriteMem intrinsics can have other strange effects.
+        HasSideEffects = true;
+    }
+  }
+
+};
+
+static void InferFromPattern(const CodeGenInstruction &Inst,
+                             bool &MayStore, bool &MayLoad,
+                             bool &HasSideEffects, bool &IsVariadic,
+                             const CodeGenDAGPatterns &CDP) {
+  MayStore = MayLoad = HasSideEffects = IsVariadic = false;
+
+  bool HadPattern =
+    InstAnalyzer(CDP, MayStore, MayLoad, HasSideEffects, IsVariadic)
+    .Analyze(Inst.TheDef);
+
+  // InstAnalyzer only correctly analyzes mayStore/mayLoad so far.
+  if (Inst.mayStore) {  // If the .td file explicitly sets mayStore, use it.
+    // If we decided that this is a store from the pattern, then the .td file
+    // entry is redundant.
+    if (MayStore)
+      fprintf(stderr,
+              "Warning: mayStore flag explicitly set on instruction '%s'"
+              " but flag already inferred from pattern.\n",
+              Inst.TheDef->getName().c_str());
+    MayStore = true;
+  }
+
+  if (Inst.mayLoad) {  // If the .td file explicitly sets mayLoad, use it.
+    // If we decided that this is a load from the pattern, then the .td file
+    // entry is redundant.
+    if (MayLoad)
+      fprintf(stderr,
+              "Warning: mayLoad flag explicitly set on instruction '%s'"
+              " but flag already inferred from pattern.\n",
+              Inst.TheDef->getName().c_str());
+    MayLoad = true;
+  }
+
+  if (Inst.neverHasSideEffects) {
+    if (HadPattern)
+      fprintf(stderr, "Warning: neverHasSideEffects set on instruction '%s' "
+              "which already has a pattern\n", Inst.TheDef->getName().c_str());
+    HasSideEffects = false;
+  }
+
+  if (Inst.hasSideEffects) {
+    if (HasSideEffects)
+      fprintf(stderr, "Warning: hasSideEffects set on instruction '%s' "
+              "which already inferred this.\n", Inst.TheDef->getName().c_str());
+    HasSideEffects = true;
+  }
+  
+  if (Inst.isVariadic)
+    IsVariadic = true;  // Can warn if we want.
+}
+
+/// ParseInstructions - Parse all of the instructions, inlining and resolving
+/// any fragments involved.  This populates the Instructions list with fully
+/// resolved instructions.
+void CodeGenDAGPatterns::ParseInstructions() {
+  std::vector<Record*> Instrs = Records.getAllDerivedDefinitions("Instruction");
+  
+  for (unsigned i = 0, e = Instrs.size(); i != e; ++i) {
+    ListInit *LI = 0;
+    
+    if (dynamic_cast<ListInit*>(Instrs[i]->getValueInit("Pattern")))
+      LI = Instrs[i]->getValueAsListInit("Pattern");
+    
+    // If there is no pattern, only collect minimal information about the
+    // instruction for its operand list.  We have to assume that there is one
+    // result, as we have no detailed info.
+    if (!LI || LI->getSize() == 0) {
+      std::vector<Record*> Results;
+      std::vector<Record*> Operands;
+      
+      CodeGenInstruction &InstInfo = Target.getInstruction(Instrs[i]);
+
+      if (InstInfo.OperandList.size() != 0) {
+        if (InstInfo.NumDefs == 0) {
+          // These produce no results
+          for (unsigned j = 0, e = InstInfo.OperandList.size(); j < e; ++j)
+            Operands.push_back(InstInfo.OperandList[j].Rec);
+        } else {
+          // Assume the first operand is the result.
+          Results.push_back(InstInfo.OperandList[0].Rec);
+      
+          // The rest are inputs.
+          for (unsigned j = 1, e = InstInfo.OperandList.size(); j < e; ++j)
+            Operands.push_back(InstInfo.OperandList[j].Rec);
+        }
+      }
+      
+      // Create and insert the instruction.
+      std::vector<Record*> ImpResults;
+      Instructions.insert(std::make_pair(Instrs[i], 
+                          DAGInstruction(0, Results, Operands, ImpResults)));
+      continue;  // no pattern.
+    }
+    
+    // Parse the instruction.
+    TreePattern *I = new TreePattern(Instrs[i], LI, true, *this);
+    // Inline pattern fragments into it.
+    I->InlinePatternFragments();
+    
+    // Infer as many types as possible.  If we cannot infer all of them, we can
+    // never do anything with this instruction pattern: report it to the user.
+    if (!I->InferAllTypes())
+      I->error("Could not infer all types in pattern!");
+    
+    // InstInputs - Keep track of all of the inputs of the instruction, along 
+    // with the record they are declared as.
+    std::map<std::string, TreePatternNode*> InstInputs;
+    
+    // InstResults - Keep track of all the virtual registers that are 'set'
+    // in the instruction, including what reg class they are.
+    std::map<std::string, TreePatternNode*> InstResults;
+
+    std::vector<Record*> InstImpResults;
+    
+    // Verify that the top-level forms in the instruction are of void type, and
+    // fill in the InstResults map.
+    for (unsigned j = 0, e = I->getNumTrees(); j != e; ++j) {
+      TreePatternNode *Pat = I->getTree(j);
+      if (Pat->getNumTypes() != 0)
+        I->error("Top-level forms in instruction pattern should have"
+                 " void types");
+
+      // Find inputs and outputs, and verify the structure of the uses/defs.
+      FindPatternInputsAndOutputs(I, Pat, InstInputs, InstResults,
+                                  InstImpResults);
+    }
+
+    // Now that we have inputs and outputs of the pattern, inspect the operands
+    // list for the instruction.  This determines the order that operands are
+    // added to the machine instruction the node corresponds to.
+    unsigned NumResults = InstResults.size();
+
+    // Parse the operands list from the (ops) list, validating it.
+    assert(I->getArgList().empty() && "Args list should still be empty here!");
+    CodeGenInstruction &CGI = Target.getInstruction(Instrs[i]);
+
+    // Check that all of the results occur first in the list.
+    std::vector<Record*> Results;
+    TreePatternNode *Res0Node = 0;
+    for (unsigned i = 0; i != NumResults; ++i) {
+      if (i == CGI.OperandList.size())
+        I->error("'" + InstResults.begin()->first +
+                 "' set but does not appear in operand list!");
+      const std::string &OpName = CGI.OperandList[i].Name;
+      
+      // Check that it exists in InstResults.
+      TreePatternNode *RNode = InstResults[OpName];
+      if (RNode == 0)
+        I->error("Operand $" + OpName + " does not exist in operand list!");
+        
+      if (i == 0)
+        Res0Node = RNode;
+      Record *R = dynamic_cast<DefInit*>(RNode->getLeafValue())->getDef();
+      if (R == 0)
+        I->error("Operand $" + OpName + " should be a set destination: all "
+                 "outputs must occur before inputs in operand list!");
+      
+      if (CGI.OperandList[i].Rec != R)
+        I->error("Operand $" + OpName + " class mismatch!");
+      
+      // Remember the return type.
+      Results.push_back(CGI.OperandList[i].Rec);
+      
+      // Okay, this one checks out.
+      InstResults.erase(OpName);
+    }
+
+    // Loop over the inputs next.  Make a copy of InstInputs so we can destroy
+    // the copy while we're checking the inputs.
+    std::map<std::string, TreePatternNode*> InstInputsCheck(InstInputs);
+
+    std::vector<TreePatternNode*> ResultNodeOperands;
+    std::vector<Record*> Operands;
+    for (unsigned i = NumResults, e = CGI.OperandList.size(); i != e; ++i) {
+      CodeGenInstruction::OperandInfo &Op = CGI.OperandList[i];
+      const std::string &OpName = Op.Name;
+      if (OpName.empty())
+        I->error("Operand #" + utostr(i) + " in operands list has no name!");
+
+      if (!InstInputsCheck.count(OpName)) {
+        // If this is an predicate operand or optional def operand with an
+        // DefaultOps set filled in, we can ignore this.  When we codegen it,
+        // we will do so as always executed.
+        if (Op.Rec->isSubClassOf("PredicateOperand") ||
+            Op.Rec->isSubClassOf("OptionalDefOperand")) {
+          // Does it have a non-empty DefaultOps field?  If so, ignore this
+          // operand.
+          if (!getDefaultOperand(Op.Rec).DefaultOps.empty())
+            continue;
+        }
+        I->error("Operand $" + OpName +
+                 " does not appear in the instruction pattern");
+      }
+      TreePatternNode *InVal = InstInputsCheck[OpName];
+      InstInputsCheck.erase(OpName);   // It occurred, remove from map.
+      
+      if (InVal->isLeaf() &&
+          dynamic_cast<DefInit*>(InVal->getLeafValue())) {
+        Record *InRec = static_cast<DefInit*>(InVal->getLeafValue())->getDef();
+        if (Op.Rec != InRec && !InRec->isSubClassOf("ComplexPattern"))
+          I->error("Operand $" + OpName + "'s register class disagrees"
+                   " between the operand and pattern");
+      }
+      Operands.push_back(Op.Rec);
+      
+      // Construct the result for the dest-pattern operand list.
+      TreePatternNode *OpNode = InVal->clone();
+      
+      // No predicate is useful on the result.
+      OpNode->clearPredicateFns();
+      
+      // Promote the xform function to be an explicit node if set.
+      if (Record *Xform = OpNode->getTransformFn()) {
+        OpNode->setTransformFn(0);
+        std::vector<TreePatternNode*> Children;
+        Children.push_back(OpNode);
+        OpNode = new TreePatternNode(Xform, Children, OpNode->getNumTypes());
+      }
+      
+      ResultNodeOperands.push_back(OpNode);
+    }
+    
+    if (!InstInputsCheck.empty())
+      I->error("Input operand $" + InstInputsCheck.begin()->first +
+               " occurs in pattern but not in operands list!");
+
+    TreePatternNode *ResultPattern =
+      new TreePatternNode(I->getRecord(), ResultNodeOperands,
+                          GetNumNodeResults(I->getRecord(), *this));
+    // Copy fully inferred output node type to instruction result pattern.
+    for (unsigned i = 0; i != NumResults; ++i)
+      ResultPattern->setType(i, Res0Node->getExtType(i));
+
+    // Create and insert the instruction.
+    // FIXME: InstImpResults should not be part of DAGInstruction.
+    DAGInstruction TheInst(I, Results, Operands, InstImpResults);
+    Instructions.insert(std::make_pair(I->getRecord(), TheInst));
+
+    // Use a temporary tree pattern to infer all types and make sure that the
+    // constructed result is correct.  This depends on the instruction already
+    // being inserted into the Instructions map.
+    TreePattern Temp(I->getRecord(), ResultPattern, false, *this);
+    Temp.InferAllTypes(&I->getNamedNodesMap());
+
+    DAGInstruction &TheInsertedInst = Instructions.find(I->getRecord())->second;
+    TheInsertedInst.setResultPattern(Temp.getOnlyTree());
+    
+    DEBUG(I->dump());
+  }
+   
+  // If we can, convert the instructions to be patterns that are matched!
+  for (std::map<Record*, DAGInstruction, RecordPtrCmp>::iterator II =
+        Instructions.begin(),
+       E = Instructions.end(); II != E; ++II) {
+    DAGInstruction &TheInst = II->second;
+    const TreePattern *I = TheInst.getPattern();
+    if (I == 0) continue;  // No pattern.
+
+    // FIXME: Assume only the first tree is the pattern. The others are clobber
+    // nodes.
+    TreePatternNode *Pattern = I->getTree(0);
+    TreePatternNode *SrcPattern;
+    if (Pattern->getOperator()->getName() == "set") {
+      SrcPattern = Pattern->getChild(Pattern->getNumChildren()-1)->clone();
+    } else{
+      // Not a set (store or something?)
+      SrcPattern = Pattern;
+    }
+    
+    Record *Instr = II->first;
+    AddPatternToMatch(I,
+                      PatternToMatch(Instr->getValueAsListInit("Predicates"),
+                                     SrcPattern,
+                                     TheInst.getResultPattern(),
+                                     TheInst.getImpResults(),
+                                     Instr->getValueAsInt("AddedComplexity"),
+                                     Instr->getID()));
+  }
+}
+
+
+typedef std::pair<const TreePatternNode*, unsigned> NameRecord;
+
+static void FindNames(const TreePatternNode *P, 
+                      std::map<std::string, NameRecord> &Names,
+                      const TreePattern *PatternTop) {
+  if (!P->getName().empty()) {
+    NameRecord &Rec = Names[P->getName()];
+    // If this is the first instance of the name, remember the node.
+    if (Rec.second++ == 0)
+      Rec.first = P;
+    else if (Rec.first->getExtTypes() != P->getExtTypes())
+      PatternTop->error("repetition of value: $" + P->getName() +
+                        " where different uses have different types!");
+  }
+  
+  if (!P->isLeaf()) {
+    for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i)
+      FindNames(P->getChild(i), Names, PatternTop);
+  }
+}
+
+void CodeGenDAGPatterns::AddPatternToMatch(const TreePattern *Pattern,
+                                           const PatternToMatch &PTM) {
+  // Do some sanity checking on the pattern we're about to match.
+  std::string Reason;
+  if (!PTM.getSrcPattern()->canPatternMatch(Reason, *this))
+    Pattern->error("Pattern can never match: " + Reason);
+  
+  // If the source pattern's root is a complex pattern, that complex pattern
+  // must specify the nodes it can potentially match.
+  if (const ComplexPattern *CP =
+        PTM.getSrcPattern()->getComplexPatternInfo(*this))
+    if (CP->getRootNodes().empty())
+      Pattern->error("ComplexPattern at root must specify list of opcodes it"
+                     " could match");
+  
+  
+  // Find all of the named values in the input and output, ensure they have the
+  // same type.
+  std::map<std::string, NameRecord> SrcNames, DstNames;
+  FindNames(PTM.getSrcPattern(), SrcNames, Pattern);
+  FindNames(PTM.getDstPattern(), DstNames, Pattern);
+
+  // Scan all of the named values in the destination pattern, rejecting them if
+  // they don't exist in the input pattern.
+  for (std::map<std::string, NameRecord>::iterator
+       I = DstNames.begin(), E = DstNames.end(); I != E; ++I) {
+    if (SrcNames[I->first].first == 0)
+      Pattern->error("Pattern has input without matching name in output: $" +
+                     I->first);
+  }
+  
+  // Scan all of the named values in the source pattern, rejecting them if the
+  // name isn't used in the dest, and isn't used to tie two values together.
+  for (std::map<std::string, NameRecord>::iterator
+       I = SrcNames.begin(), E = SrcNames.end(); I != E; ++I)
+    if (DstNames[I->first].first == 0 && SrcNames[I->first].second == 1)
+      Pattern->error("Pattern has dead named input: $" + I->first);
+  
+  PatternsToMatch.push_back(PTM);
+}
+
+
+
+void CodeGenDAGPatterns::InferInstructionFlags() {
+  const std::vector<const CodeGenInstruction*> &Instructions =
+    Target.getInstructionsByEnumValue();
+  for (unsigned i = 0, e = Instructions.size(); i != e; ++i) {
+    CodeGenInstruction &InstInfo =
+      const_cast<CodeGenInstruction &>(*Instructions[i]);
+    // Determine properties of the instruction from its pattern.
+    bool MayStore, MayLoad, HasSideEffects, IsVariadic;
+    InferFromPattern(InstInfo, MayStore, MayLoad, HasSideEffects, IsVariadic,
+                     *this);
+    InstInfo.mayStore = MayStore;
+    InstInfo.mayLoad = MayLoad;
+    InstInfo.hasSideEffects = HasSideEffects;
+    InstInfo.isVariadic = IsVariadic;
+  }
+}
+
+/// Given a pattern result with an unresolved type, see if we can find one
+/// instruction with an unresolved result type.  Force this result type to an
+/// arbitrary element if it's possible types to converge results.
+static bool ForceArbitraryInstResultType(TreePatternNode *N, TreePattern &TP) {
+  if (N->isLeaf())
+    return false;
+  
+  // Analyze children.
+  for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
+    if (ForceArbitraryInstResultType(N->getChild(i), TP))
+      return true;
+
+  if (!N->getOperator()->isSubClassOf("Instruction"))
+    return false;
+
+  // If this type is already concrete or completely unknown we can't do
+  // anything.
+  for (unsigned i = 0, e = N->getNumTypes(); i != e; ++i) {
+    if (N->getExtType(i).isCompletelyUnknown() || N->getExtType(i).isConcrete())
+      continue;
+  
+    // Otherwise, force its type to the first possibility (an arbitrary choice).
+    if (N->getExtType(i).MergeInTypeInfo(N->getExtType(i).getTypeList()[0], TP))
+      return true;
+  }
+  
+  return false;
+}
+
+void CodeGenDAGPatterns::ParsePatterns() {
+  std::vector<Record*> Patterns = Records.getAllDerivedDefinitions("Pattern");
+
+  for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
+    Record *CurPattern = Patterns[i];
+    DagInit *Tree = CurPattern->getValueAsDag("PatternToMatch");
+    TreePattern *Pattern = new TreePattern(CurPattern, Tree, true, *this);
+
+    // Inline pattern fragments into it.
+    Pattern->InlinePatternFragments();
+    
+    ListInit *LI = CurPattern->getValueAsListInit("ResultInstrs");
+    if (LI->getSize() == 0) continue;  // no pattern.
+    
+    // Parse the instruction.
+    TreePattern *Result = new TreePattern(CurPattern, LI, false, *this);
+    
+    // Inline pattern fragments into it.
+    Result->InlinePatternFragments();
+
+    if (Result->getNumTrees() != 1)
+      Result->error("Cannot handle instructions producing instructions "
+                    "with temporaries yet!");
+    
+    bool IterateInference;
+    bool InferredAllPatternTypes, InferredAllResultTypes;
+    do {
+      // Infer as many types as possible.  If we cannot infer all of them, we
+      // can never do anything with this pattern: report it to the user.
+      InferredAllPatternTypes =
+        Pattern->InferAllTypes(&Pattern->getNamedNodesMap());
+      
+      // Infer as many types as possible.  If we cannot infer all of them, we
+      // can never do anything with this pattern: report it to the user.
+      InferredAllResultTypes =
+        Result->InferAllTypes(&Pattern->getNamedNodesMap());
+
+      IterateInference = false;
+      
+      // Apply the type of the result to the source pattern.  This helps us
+      // resolve cases where the input type is known to be a pointer type (which
+      // is considered resolved), but the result knows it needs to be 32- or
+      // 64-bits.  Infer the other way for good measure.
+      for (unsigned i = 0, e = std::min(Result->getTree(0)->getNumTypes(),
+                                        Pattern->getTree(0)->getNumTypes());
+           i != e; ++i) {
+        IterateInference = Pattern->getTree(0)->
+          UpdateNodeType(i, Result->getTree(0)->getExtType(i), *Result);
+        IterateInference |= Result->getTree(0)->
+          UpdateNodeType(i, Pattern->getTree(0)->getExtType(i), *Result);
+      }
+      
+      // If our iteration has converged and the input pattern's types are fully
+      // resolved but the result pattern is not fully resolved, we may have a
+      // situation where we have two instructions in the result pattern and
+      // the instructions require a common register class, but don't care about
+      // what actual MVT is used.  This is actually a bug in our modelling:
+      // output patterns should have register classes, not MVTs.
+      //
+      // In any case, to handle this, we just go through and disambiguate some
+      // arbitrary types to the result pattern's nodes.
+      if (!IterateInference && InferredAllPatternTypes &&
+          !InferredAllResultTypes)
+        IterateInference = ForceArbitraryInstResultType(Result->getTree(0),
+                                                        *Result);
+    } while (IterateInference);
+    
+    // Verify that we inferred enough types that we can do something with the
+    // pattern and result.  If these fire the user has to add type casts.
+    if (!InferredAllPatternTypes)
+      Pattern->error("Could not infer all types in pattern!");
+    if (!InferredAllResultTypes) {
+      Pattern->dump();
+      Result->error("Could not infer all types in pattern result!");
+    }
+    
+    // Validate that the input pattern is correct.
+    std::map<std::string, TreePatternNode*> InstInputs;
+    std::map<std::string, TreePatternNode*> InstResults;
+    std::vector<Record*> InstImpResults;
+    for (unsigned j = 0, ee = Pattern->getNumTrees(); j != ee; ++j)
+      FindPatternInputsAndOutputs(Pattern, Pattern->getTree(j),
+                                  InstInputs, InstResults,
+                                  InstImpResults);
+
+    // Promote the xform function to be an explicit node if set.
+    TreePatternNode *DstPattern = Result->getOnlyTree();
+    std::vector<TreePatternNode*> ResultNodeOperands;
+    for (unsigned ii = 0, ee = DstPattern->getNumChildren(); ii != ee; ++ii) {
+      TreePatternNode *OpNode = DstPattern->getChild(ii);
+      if (Record *Xform = OpNode->getTransformFn()) {
+        OpNode->setTransformFn(0);
+        std::vector<TreePatternNode*> Children;
+        Children.push_back(OpNode);
+        OpNode = new TreePatternNode(Xform, Children, OpNode->getNumTypes());
+      }
+      ResultNodeOperands.push_back(OpNode);
+    }
+    DstPattern = Result->getOnlyTree();
+    if (!DstPattern->isLeaf())
+      DstPattern = new TreePatternNode(DstPattern->getOperator(),
+                                       ResultNodeOperands,
+                                       DstPattern->getNumTypes());
+    
+    for (unsigned i = 0, e = Result->getOnlyTree()->getNumTypes(); i != e; ++i)
+      DstPattern->setType(i, Result->getOnlyTree()->getExtType(i));
+    
+    TreePattern Temp(Result->getRecord(), DstPattern, false, *this);
+    Temp.InferAllTypes();
+
+    
+    AddPatternToMatch(Pattern,
+                    PatternToMatch(CurPattern->getValueAsListInit("Predicates"),
+                                   Pattern->getTree(0),
+                                   Temp.getOnlyTree(), InstImpResults,
+                                   CurPattern->getValueAsInt("AddedComplexity"),
+                                   CurPattern->getID()));
+  }
+}
+
+/// CombineChildVariants - Given a bunch of permutations of each child of the
+/// 'operator' node, put them together in all possible ways.
+static void CombineChildVariants(TreePatternNode *Orig, 
+               const std::vector<std::vector<TreePatternNode*> > &ChildVariants,
+                                 std::vector<TreePatternNode*> &OutVariants,
+                                 CodeGenDAGPatterns &CDP,
+                                 const MultipleUseVarSet &DepVars) {
+  // Make sure that each operand has at least one variant to choose from.
+  for (unsigned i = 0, e = ChildVariants.size(); i != e; ++i)
+    if (ChildVariants[i].empty())
+      return;
+        
+  // The end result is an all-pairs construction of the resultant pattern.
+  std::vector<unsigned> Idxs;
+  Idxs.resize(ChildVariants.size());
+  bool NotDone;
+  do {
+#ifndef NDEBUG
+    DEBUG(if (!Idxs.empty()) {
+            errs() << Orig->getOperator()->getName() << ": Idxs = [ ";
+              for (unsigned i = 0; i < Idxs.size(); ++i) {
+                errs() << Idxs[i] << " ";
+            }
+            errs() << "]\n";
+          });
+#endif
+    // Create the variant and add it to the output list.
+    std::vector<TreePatternNode*> NewChildren;
+    for (unsigned i = 0, e = ChildVariants.size(); i != e; ++i)
+      NewChildren.push_back(ChildVariants[i][Idxs[i]]);
+    TreePatternNode *R = new TreePatternNode(Orig->getOperator(), NewChildren,
+                                             Orig->getNumTypes());
+    
+    // Copy over properties.
+    R->setName(Orig->getName());
+    R->setPredicateFns(Orig->getPredicateFns());
+    R->setTransformFn(Orig->getTransformFn());
+    for (unsigned i = 0, e = Orig->getNumTypes(); i != e; ++i)
+      R->setType(i, Orig->getExtType(i));
+    
+    // If this pattern cannot match, do not include it as a variant.
+    std::string ErrString;
+    if (!R->canPatternMatch(ErrString, CDP)) {
+      delete R;
+    } else {
+      bool AlreadyExists = false;
+      
+      // Scan to see if this pattern has already been emitted.  We can get
+      // duplication due to things like commuting:
+      //   (and GPRC:$a, GPRC:$b) -> (and GPRC:$b, GPRC:$a)
+      // which are the same pattern.  Ignore the dups.
+      for (unsigned i = 0, e = OutVariants.size(); i != e; ++i)
+        if (R->isIsomorphicTo(OutVariants[i], DepVars)) {
+          AlreadyExists = true;
+          break;
+        }
+      
+      if (AlreadyExists)
+        delete R;
+      else
+        OutVariants.push_back(R);
+    }
+    
+    // Increment indices to the next permutation by incrementing the
+    // indicies from last index backward, e.g., generate the sequence
+    // [0, 0], [0, 1], [1, 0], [1, 1].
+    int IdxsIdx;
+    for (IdxsIdx = Idxs.size() - 1; IdxsIdx >= 0; --IdxsIdx) {
+      if (++Idxs[IdxsIdx] == ChildVariants[IdxsIdx].size())
+        Idxs[IdxsIdx] = 0;
+      else
+        break;
+    }
+    NotDone = (IdxsIdx >= 0);
+  } while (NotDone);
+}
+
+/// CombineChildVariants - A helper function for binary operators.
+///
+static void CombineChildVariants(TreePatternNode *Orig, 
+                                 const std::vector<TreePatternNode*> &LHS,
+                                 const std::vector<TreePatternNode*> &RHS,
+                                 std::vector<TreePatternNode*> &OutVariants,
+                                 CodeGenDAGPatterns &CDP,
+                                 const MultipleUseVarSet &DepVars) {
+  std::vector<std::vector<TreePatternNode*> > ChildVariants;
+  ChildVariants.push_back(LHS);
+  ChildVariants.push_back(RHS);
+  CombineChildVariants(Orig, ChildVariants, OutVariants, CDP, DepVars);
+}  
+
+
+static void GatherChildrenOfAssociativeOpcode(TreePatternNode *N,
+                                     std::vector<TreePatternNode *> &Children) {
+  assert(N->getNumChildren()==2 &&"Associative but doesn't have 2 children!");
+  Record *Operator = N->getOperator();
+  
+  // Only permit raw nodes.
+  if (!N->getName().empty() || !N->getPredicateFns().empty() ||
+      N->getTransformFn()) {
+    Children.push_back(N);
+    return;
+  }
+
+  if (N->getChild(0)->isLeaf() || N->getChild(0)->getOperator() != Operator)
+    Children.push_back(N->getChild(0));
+  else
+    GatherChildrenOfAssociativeOpcode(N->getChild(0), Children);
+
+  if (N->getChild(1)->isLeaf() || N->getChild(1)->getOperator() != Operator)
+    Children.push_back(N->getChild(1));
+  else
+    GatherChildrenOfAssociativeOpcode(N->getChild(1), Children);
+}
+
+/// GenerateVariantsOf - Given a pattern N, generate all permutations we can of
+/// the (potentially recursive) pattern by using algebraic laws.
+///
+static void GenerateVariantsOf(TreePatternNode *N,
+                               std::vector<TreePatternNode*> &OutVariants,
+                               CodeGenDAGPatterns &CDP,
+                               const MultipleUseVarSet &DepVars) {
+  // We cannot permute leaves.
+  if (N->isLeaf()) {
+    OutVariants.push_back(N);
+    return;
+  }
+
+  // Look up interesting info about the node.
+  const SDNodeInfo &NodeInfo = CDP.getSDNodeInfo(N->getOperator());
+
+  // If this node is associative, re-associate.
+  if (NodeInfo.hasProperty(SDNPAssociative)) {
+    // Re-associate by pulling together all of the linked operators 
+    std::vector<TreePatternNode*> MaximalChildren;
+    GatherChildrenOfAssociativeOpcode(N, MaximalChildren);
+
+    // Only handle child sizes of 3.  Otherwise we'll end up trying too many
+    // permutations.
+    if (MaximalChildren.size() == 3) {
+      // Find the variants of all of our maximal children.
+      std::vector<TreePatternNode*> AVariants, BVariants, CVariants;
+      GenerateVariantsOf(MaximalChildren[0], AVariants, CDP, DepVars);
+      GenerateVariantsOf(MaximalChildren[1], BVariants, CDP, DepVars);
+      GenerateVariantsOf(MaximalChildren[2], CVariants, CDP, DepVars);
+      
+      // There are only two ways we can permute the tree:
+      //   (A op B) op C    and    A op (B op C)
+      // Within these forms, we can also permute A/B/C.
+      
+      // Generate legal pair permutations of A/B/C.
+      std::vector<TreePatternNode*> ABVariants;
+      std::vector<TreePatternNode*> BAVariants;
+      std::vector<TreePatternNode*> ACVariants;
+      std::vector<TreePatternNode*> CAVariants;
+      std::vector<TreePatternNode*> BCVariants;
+      std::vector<TreePatternNode*> CBVariants;
+      CombineChildVariants(N, AVariants, BVariants, ABVariants, CDP, DepVars);
+      CombineChildVariants(N, BVariants, AVariants, BAVariants, CDP, DepVars);
+      CombineChildVariants(N, AVariants, CVariants, ACVariants, CDP, DepVars);
+      CombineChildVariants(N, CVariants, AVariants, CAVariants, CDP, DepVars);
+      CombineChildVariants(N, BVariants, CVariants, BCVariants, CDP, DepVars);
+      CombineChildVariants(N, CVariants, BVariants, CBVariants, CDP, DepVars);
+
+      // Combine those into the result: (x op x) op x
+      CombineChildVariants(N, ABVariants, CVariants, OutVariants, CDP, DepVars);
+      CombineChildVariants(N, BAVariants, CVariants, OutVariants, CDP, DepVars);
+      CombineChildVariants(N, ACVariants, BVariants, OutVariants, CDP, DepVars);
+      CombineChildVariants(N, CAVariants, BVariants, OutVariants, CDP, DepVars);
+      CombineChildVariants(N, BCVariants, AVariants, OutVariants, CDP, DepVars);
+      CombineChildVariants(N, CBVariants, AVariants, OutVariants, CDP, DepVars);
+
+      // Combine those into the result: x op (x op x)
+      CombineChildVariants(N, CVariants, ABVariants, OutVariants, CDP, DepVars);
+      CombineChildVariants(N, CVariants, BAVariants, OutVariants, CDP, DepVars);
+      CombineChildVariants(N, BVariants, ACVariants, OutVariants, CDP, DepVars);
+      CombineChildVariants(N, BVariants, CAVariants, OutVariants, CDP, DepVars);
+      CombineChildVariants(N, AVariants, BCVariants, OutVariants, CDP, DepVars);
+      CombineChildVariants(N, AVariants, CBVariants, OutVariants, CDP, DepVars);
+      return;
+    }
+  }
+  
+  // Compute permutations of all children.
+  std::vector<std::vector<TreePatternNode*> > ChildVariants;
+  ChildVariants.resize(N->getNumChildren());
+  for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
+    GenerateVariantsOf(N->getChild(i), ChildVariants[i], CDP, DepVars);
+
+  // Build all permutations based on how the children were formed.
+  CombineChildVariants(N, ChildVariants, OutVariants, CDP, DepVars);
+
+  // If this node is commutative, consider the commuted order.
+  bool isCommIntrinsic = N->isCommutativeIntrinsic(CDP);
+  if (NodeInfo.hasProperty(SDNPCommutative) || isCommIntrinsic) {
+    assert((N->getNumChildren()==2 || isCommIntrinsic) &&
+           "Commutative but doesn't have 2 children!");
+    // Don't count children which are actually register references.
+    unsigned NC = 0;
+    for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
+      TreePatternNode *Child = N->getChild(i);
+      if (Child->isLeaf())
+        if (DefInit *DI = dynamic_cast<DefInit*>(Child->getLeafValue())) {
+          Record *RR = DI->getDef();
+          if (RR->isSubClassOf("Register"))
+            continue;
+        }
+      NC++;
+    }
+    // Consider the commuted order.
+    if (isCommIntrinsic) {
+      // Commutative intrinsic. First operand is the intrinsic id, 2nd and 3rd
+      // operands are the commutative operands, and there might be more operands
+      // after those.
+      assert(NC >= 3 &&
+             "Commutative intrinsic should have at least 3 childrean!");
+      std::vector<std::vector<TreePatternNode*> > Variants;
+      Variants.push_back(ChildVariants[0]); // Intrinsic id.
+      Variants.push_back(ChildVariants[2]);
+      Variants.push_back(ChildVariants[1]);
+      for (unsigned i = 3; i != NC; ++i)
+        Variants.push_back(ChildVariants[i]);
+      CombineChildVariants(N, Variants, OutVariants, CDP, DepVars);
+    } else if (NC == 2)
+      CombineChildVariants(N, ChildVariants[1], ChildVariants[0],
+                           OutVariants, CDP, DepVars);
+  }
+}
+
+
+// GenerateVariants - Generate variants.  For example, commutative patterns can
+// match multiple ways.  Add them to PatternsToMatch as well.
+void CodeGenDAGPatterns::GenerateVariants() {
+  DEBUG(errs() << "Generating instruction variants.\n");
+  
+  // Loop over all of the patterns we've collected, checking to see if we can
+  // generate variants of the instruction, through the exploitation of
+  // identities.  This permits the target to provide aggressive matching without
+  // the .td file having to contain tons of variants of instructions.
+  //
+  // Note that this loop adds new patterns to the PatternsToMatch list, but we
+  // intentionally do not reconsider these.  Any variants of added patterns have
+  // already been added.
+  //
+  for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) {
+    MultipleUseVarSet             DepVars;
+    std::vector<TreePatternNode*> Variants;
+    FindDepVars(PatternsToMatch[i].getSrcPattern(), DepVars);
+    DEBUG(errs() << "Dependent/multiply used variables: ");
+    DEBUG(DumpDepVars(DepVars));
+    DEBUG(errs() << "\n");
+    GenerateVariantsOf(PatternsToMatch[i].getSrcPattern(), Variants, *this, DepVars);
+
+    assert(!Variants.empty() && "Must create at least original variant!");
+    Variants.erase(Variants.begin());  // Remove the original pattern.
+
+    if (Variants.empty())  // No variants for this pattern.
+      continue;
+
+    DEBUG(errs() << "FOUND VARIANTS OF: ";
+          PatternsToMatch[i].getSrcPattern()->dump();
+          errs() << "\n");
+
+    for (unsigned v = 0, e = Variants.size(); v != e; ++v) {
+      TreePatternNode *Variant = Variants[v];
+
+      DEBUG(errs() << "  VAR#" << v <<  ": ";
+            Variant->dump();
+            errs() << "\n");
+      
+      // Scan to see if an instruction or explicit pattern already matches this.
+      bool AlreadyExists = false;
+      for (unsigned p = 0, e = PatternsToMatch.size(); p != e; ++p) {
+        // Skip if the top level predicates do not match.
+        if (PatternsToMatch[i].getPredicates() !=
+            PatternsToMatch[p].getPredicates())
+          continue;
+        // Check to see if this variant already exists.
+        if (Variant->isIsomorphicTo(PatternsToMatch[p].getSrcPattern(), DepVars)) {
+          DEBUG(errs() << "  *** ALREADY EXISTS, ignoring variant.\n");
+          AlreadyExists = true;
+          break;
+        }
+      }
+      // If we already have it, ignore the variant.
+      if (AlreadyExists) continue;
+
+      // Otherwise, add it to the list of patterns we have.
+      PatternsToMatch.
+        push_back(PatternToMatch(PatternsToMatch[i].getPredicates(),
+                                 Variant, PatternsToMatch[i].getDstPattern(),
+                                 PatternsToMatch[i].getDstRegs(),
+                                 PatternsToMatch[i].getAddedComplexity(),
+                                 Record::getNewUID()));
+    }
+
+    DEBUG(errs() << "\n");
+  }
+}
+
diff --git a/src/LLVM/utils/TableGen/CodeGenDAGPatterns.h b/src/LLVM/utils/TableGen/CodeGenDAGPatterns.h
new file mode 100644
index 0000000..0a1362a
--- /dev/null
+++ b/src/LLVM/utils/TableGen/CodeGenDAGPatterns.h
@@ -0,0 +1,748 @@
+//===- CodeGenDAGPatterns.h - Read DAG patterns from .td file ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the CodeGenDAGPatterns class, which is used to read and
+// represent the patterns present in a .td file for instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CODEGEN_DAGPATTERNS_H
+#define CODEGEN_DAGPATTERNS_H
+
+#include "CodeGenTarget.h"
+#include "CodeGenIntrinsics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include <set>
+#include <algorithm>
+#include <vector>
+#include <map>
+
+namespace llvm {
+  class Record;
+  struct Init;
+  class ListInit;
+  class DagInit;
+  class SDNodeInfo;
+  class TreePattern;
+  class TreePatternNode;
+  class CodeGenDAGPatterns;
+  class ComplexPattern;
+
+/// EEVT::DAGISelGenValueType - These are some extended forms of
+/// MVT::SimpleValueType that we use as lattice values during type inference.
+/// The existing MVT iAny, fAny and vAny types suffice to represent
+/// arbitrary integer, floating-point, and vector types, so only an unknown
+/// value is needed.
+namespace EEVT {
+  /// TypeSet - This is either empty if it's completely unknown, or holds a set
+  /// of types.  It is used during type inference because register classes can
+  /// have multiple possible types and we don't know which one they get until
+  /// type inference is complete.
+  ///
+  /// TypeSet can have three states:
+  ///    Vector is empty: The type is completely unknown, it can be any valid
+  ///       target type.
+  ///    Vector has multiple constrained types: (e.g. v4i32 + v4f32) it is one
+  ///       of those types only.
+  ///    Vector has one concrete type: The type is completely known.
+  ///
+  class TypeSet {
+    SmallVector<MVT::SimpleValueType, 4> TypeVec;
+  public:
+    TypeSet() {}
+    TypeSet(MVT::SimpleValueType VT, TreePattern &TP);
+    TypeSet(const std::vector<MVT::SimpleValueType> &VTList);    
+    
+    bool isCompletelyUnknown() const { return TypeVec.empty(); }
+    
+    bool isConcrete() const {
+      if (TypeVec.size() != 1) return false;
+      unsigned char T = TypeVec[0]; (void)T;
+      assert(T < MVT::LAST_VALUETYPE || T == MVT::iPTR || T == MVT::iPTRAny);
+      return true;
+    }
+    
+    MVT::SimpleValueType getConcrete() const {
+      assert(isConcrete() && "Type isn't concrete yet");
+      return (MVT::SimpleValueType)TypeVec[0];
+    }
+    
+    bool isDynamicallyResolved() const {
+      return getConcrete() == MVT::iPTR || getConcrete() == MVT::iPTRAny;
+    }
+    
+    const SmallVectorImpl<MVT::SimpleValueType> &getTypeList() const {
+      assert(!TypeVec.empty() && "Not a type list!");
+      return TypeVec;
+    }
+    
+    bool isVoid() const {
+      return TypeVec.size() == 1 && TypeVec[0] == MVT::isVoid;
+    }
+    
+    /// hasIntegerTypes - Return true if this TypeSet contains any integer value
+    /// types.
+    bool hasIntegerTypes() const;
+    
+    /// hasFloatingPointTypes - Return true if this TypeSet contains an fAny or
+    /// a floating point value type.
+    bool hasFloatingPointTypes() const;
+    
+    /// hasVectorTypes - Return true if this TypeSet contains a vector value
+    /// type.
+    bool hasVectorTypes() const;
+    
+    /// getName() - Return this TypeSet as a string.
+    std::string getName() const;
+    
+    /// MergeInTypeInfo - This merges in type information from the specified
+    /// argument.  If 'this' changes, it returns true.  If the two types are
+    /// contradictory (e.g. merge f32 into i32) then this throws an exception.
+    bool MergeInTypeInfo(const EEVT::TypeSet &InVT, TreePattern &TP);
+
+    bool MergeInTypeInfo(MVT::SimpleValueType InVT, TreePattern &TP) {
+      return MergeInTypeInfo(EEVT::TypeSet(InVT, TP), TP);
+    }
+
+    /// Force this type list to only contain integer types.
+    bool EnforceInteger(TreePattern &TP);
+
+    /// Force this type list to only contain floating point types.
+    bool EnforceFloatingPoint(TreePattern &TP);
+
+    /// EnforceScalar - Remove all vector types from this type list.
+    bool EnforceScalar(TreePattern &TP);
+
+    /// EnforceVector - Remove all non-vector types from this type list.
+    bool EnforceVector(TreePattern &TP);
+
+    /// EnforceSmallerThan - 'this' must be a smaller VT than Other.  Update
+    /// this an other based on this information.
+    bool EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP);
+    
+    /// EnforceVectorEltTypeIs - 'this' is now constrainted to be a vector type
+    /// whose element is VT.
+    bool EnforceVectorEltTypeIs(EEVT::TypeSet &VT, TreePattern &TP);
+    
+    bool operator!=(const TypeSet &RHS) const { return TypeVec != RHS.TypeVec; }
+    bool operator==(const TypeSet &RHS) const { return TypeVec == RHS.TypeVec; }
+    
+  private:
+    /// FillWithPossibleTypes - Set to all legal types and return true, only
+    /// valid on completely unknown type sets.  If Pred is non-null, only MVTs
+    /// that pass the predicate are added.
+    bool FillWithPossibleTypes(TreePattern &TP,
+                               bool (*Pred)(MVT::SimpleValueType) = 0,
+                               const char *PredicateName = 0);
+  };
+}
+
+/// Set type used to track multiply used variables in patterns
+typedef std::set<std::string> MultipleUseVarSet;
+
+/// SDTypeConstraint - This is a discriminated union of constraints,
+/// corresponding to the SDTypeConstraint tablegen class in Target.td.
+struct SDTypeConstraint {
+  SDTypeConstraint(Record *R);
+  
+  unsigned OperandNo;   // The operand # this constraint applies to.
+  enum { 
+    SDTCisVT, SDTCisPtrTy, SDTCisInt, SDTCisFP, SDTCisVec, SDTCisSameAs, 
+    SDTCisVTSmallerThanOp, SDTCisOpSmallerThanOp, SDTCisEltOfVec
+  } ConstraintType;
+  
+  union {   // The discriminated union.
+    struct {
+      MVT::SimpleValueType VT;
+    } SDTCisVT_Info;
+    struct {
+      unsigned OtherOperandNum;
+    } SDTCisSameAs_Info;
+    struct {
+      unsigned OtherOperandNum;
+    } SDTCisVTSmallerThanOp_Info;
+    struct {
+      unsigned BigOperandNum;
+    } SDTCisOpSmallerThanOp_Info;
+    struct {
+      unsigned OtherOperandNum;
+    } SDTCisEltOfVec_Info;
+  } x;
+
+  /// ApplyTypeConstraint - Given a node in a pattern, apply this type
+  /// constraint to the nodes operands.  This returns true if it makes a
+  /// change, false otherwise.  If a type contradiction is found, throw an
+  /// exception.
+  bool ApplyTypeConstraint(TreePatternNode *N, const SDNodeInfo &NodeInfo,
+                           TreePattern &TP) const;
+};
+
+/// SDNodeInfo - One of these records is created for each SDNode instance in
+/// the target .td file.  This represents the various dag nodes we will be
+/// processing.
+class SDNodeInfo {
+  Record *Def;
+  std::string EnumName;
+  std::string SDClassName;
+  unsigned Properties;
+  unsigned NumResults;
+  int NumOperands;
+  std::vector<SDTypeConstraint> TypeConstraints;
+public:
+  SDNodeInfo(Record *R);  // Parse the specified record.
+  
+  unsigned getNumResults() const { return NumResults; }
+  
+  /// getNumOperands - This is the number of operands required or -1 if
+  /// variadic.
+  int getNumOperands() const { return NumOperands; }
+  Record *getRecord() const { return Def; }
+  const std::string &getEnumName() const { return EnumName; }
+  const std::string &getSDClassName() const { return SDClassName; }
+  
+  const std::vector<SDTypeConstraint> &getTypeConstraints() const {
+    return TypeConstraints;
+  }
+  
+  /// getKnownType - If the type constraints on this node imply a fixed type
+  /// (e.g. all stores return void, etc), then return it as an
+  /// MVT::SimpleValueType.  Otherwise, return MVT::Other.
+  MVT::SimpleValueType getKnownType(unsigned ResNo) const;
+  
+  /// hasProperty - Return true if this node has the specified property.
+  ///
+  bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); }
+
+  /// ApplyTypeConstraints - Given a node in a pattern, apply the type
+  /// constraints for this node to the operands of the node.  This returns
+  /// true if it makes a change, false otherwise.  If a type contradiction is
+  /// found, throw an exception.
+  bool ApplyTypeConstraints(TreePatternNode *N, TreePattern &TP) const {
+    bool MadeChange = false;
+    for (unsigned i = 0, e = TypeConstraints.size(); i != e; ++i)
+      MadeChange |= TypeConstraints[i].ApplyTypeConstraint(N, *this, TP);
+    return MadeChange;
+  }
+};
+
+/// FIXME: TreePatternNode's can be shared in some cases (due to dag-shaped
+/// patterns), and as such should be ref counted.  We currently just leak all
+/// TreePatternNode objects!
+class TreePatternNode {
+  /// The type of each node result.  Before and during type inference, each
+  /// result may be a set of possible types.  After (successful) type inference,
+  /// each is a single concrete type.
+  SmallVector<EEVT::TypeSet, 1> Types;
+  
+  /// Operator - The Record for the operator if this is an interior node (not
+  /// a leaf).
+  Record *Operator;
+  
+  /// Val - The init value (e.g. the "GPRC" record, or "7") for a leaf.
+  ///
+  Init *Val;
+  
+  /// Name - The name given to this node with the :$foo notation.
+  ///
+  std::string Name;
+  
+  /// PredicateFns - The predicate functions to execute on this node to check
+  /// for a match.  If this list is empty, no predicate is involved.
+  std::vector<std::string> PredicateFns;
+  
+  /// TransformFn - The transformation function to execute on this node before
+  /// it can be substituted into the resulting instruction on a pattern match.
+  Record *TransformFn;
+  
+  std::vector<TreePatternNode*> Children;
+public:
+  TreePatternNode(Record *Op, const std::vector<TreePatternNode*> &Ch,
+                  unsigned NumResults) 
+    : Operator(Op), Val(0), TransformFn(0), Children(Ch) {
+    Types.resize(NumResults);
+  }
+  TreePatternNode(Init *val, unsigned NumResults)    // leaf ctor
+    : Operator(0), Val(val), TransformFn(0) {
+    Types.resize(NumResults);
+  }
+  ~TreePatternNode();
+  
+  const std::string &getName() const { return Name; }
+  void setName(StringRef N) { Name.assign(N.begin(), N.end()); }
+  
+  bool isLeaf() const { return Val != 0; }
+  
+  // Type accessors.
+  unsigned getNumTypes() const { return Types.size(); }
+  MVT::SimpleValueType getType(unsigned ResNo) const {
+    return Types[ResNo].getConcrete();
+  }
+  const SmallVectorImpl<EEVT::TypeSet> &getExtTypes() const { return Types; }
+  const EEVT::TypeSet &getExtType(unsigned ResNo) const { return Types[ResNo]; }
+  EEVT::TypeSet &getExtType(unsigned ResNo) { return Types[ResNo]; }
+  void setType(unsigned ResNo, const EEVT::TypeSet &T) { Types[ResNo] = T; }
+  
+  bool hasTypeSet(unsigned ResNo) const {
+    return Types[ResNo].isConcrete();
+  }
+  bool isTypeCompletelyUnknown(unsigned ResNo) const {
+    return Types[ResNo].isCompletelyUnknown();
+  }
+  bool isTypeDynamicallyResolved(unsigned ResNo) const {
+    return Types[ResNo].isDynamicallyResolved();
+  }
+  
+  Init *getLeafValue() const { assert(isLeaf()); return Val; }
+  Record *getOperator() const { assert(!isLeaf()); return Operator; }
+  
+  unsigned getNumChildren() const { return Children.size(); }
+  TreePatternNode *getChild(unsigned N) const { return Children[N]; }
+  void setChild(unsigned i, TreePatternNode *N) {
+    Children[i] = N;
+  }
+  
+  /// hasChild - Return true if N is any of our children.
+  bool hasChild(const TreePatternNode *N) const {
+    for (unsigned i = 0, e = Children.size(); i != e; ++i)
+      if (Children[i] == N) return true;
+    return false;
+  }
+
+  const std::vector<std::string> &getPredicateFns() const {return PredicateFns;}
+  void clearPredicateFns() { PredicateFns.clear(); }
+  void setPredicateFns(const std::vector<std::string> &Fns) {
+    assert(PredicateFns.empty() && "Overwriting non-empty predicate list!");
+    PredicateFns = Fns;
+  }
+  void addPredicateFn(const std::string &Fn) { 
+    assert(!Fn.empty() && "Empty predicate string!");
+    if (std::find(PredicateFns.begin(), PredicateFns.end(), Fn) ==
+          PredicateFns.end())
+      PredicateFns.push_back(Fn);
+  }
+
+  Record *getTransformFn() const { return TransformFn; }
+  void setTransformFn(Record *Fn) { TransformFn = Fn; }
+  
+  /// getIntrinsicInfo - If this node corresponds to an intrinsic, return the
+  /// CodeGenIntrinsic information for it, otherwise return a null pointer.
+  const CodeGenIntrinsic *getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const;
+
+  /// getComplexPatternInfo - If this node corresponds to a ComplexPattern,
+  /// return the ComplexPattern information, otherwise return null.
+  const ComplexPattern *
+  getComplexPatternInfo(const CodeGenDAGPatterns &CGP) const;
+
+  /// NodeHasProperty - Return true if this node has the specified property.
+  bool NodeHasProperty(SDNP Property, const CodeGenDAGPatterns &CGP) const;
+  
+  /// TreeHasProperty - Return true if any node in this tree has the specified
+  /// property.
+  bool TreeHasProperty(SDNP Property, const CodeGenDAGPatterns &CGP) const;
+  
+  /// isCommutativeIntrinsic - Return true if the node is an intrinsic which is
+  /// marked isCommutative.
+  bool isCommutativeIntrinsic(const CodeGenDAGPatterns &CDP) const;
+  
+  void print(raw_ostream &OS) const;
+  void dump() const;
+  
+public:   // Higher level manipulation routines.
+
+  /// clone - Return a new copy of this tree.
+  ///
+  TreePatternNode *clone() const;
+
+  /// RemoveAllTypes - Recursively strip all the types of this tree.
+  void RemoveAllTypes();
+  
+  /// isIsomorphicTo - Return true if this node is recursively isomorphic to
+  /// the specified node.  For this comparison, all of the state of the node
+  /// is considered, except for the assigned name.  Nodes with differing names
+  /// that are otherwise identical are considered isomorphic.
+  bool isIsomorphicTo(const TreePatternNode *N,
+                      const MultipleUseVarSet &DepVars) const;
+  
+  /// SubstituteFormalArguments - Replace the formal arguments in this tree
+  /// with actual values specified by ArgMap.
+  void SubstituteFormalArguments(std::map<std::string,
+                                          TreePatternNode*> &ArgMap);
+
+  /// InlinePatternFragments - If this pattern refers to any pattern
+  /// fragments, inline them into place, giving us a pattern without any
+  /// PatFrag references.
+  TreePatternNode *InlinePatternFragments(TreePattern &TP);
+  
+  /// ApplyTypeConstraints - Apply all of the type constraints relevant to
+  /// this node and its children in the tree.  This returns true if it makes a
+  /// change, false otherwise.  If a type contradiction is found, throw an
+  /// exception.
+  bool ApplyTypeConstraints(TreePattern &TP, bool NotRegisters);
+  
+  /// UpdateNodeType - Set the node type of N to VT if VT contains
+  /// information.  If N already contains a conflicting type, then throw an
+  /// exception.  This returns true if any information was updated.
+  ///
+  bool UpdateNodeType(unsigned ResNo, const EEVT::TypeSet &InTy,
+                      TreePattern &TP) {
+    return Types[ResNo].MergeInTypeInfo(InTy, TP);
+  }
+
+  bool UpdateNodeType(unsigned ResNo, MVT::SimpleValueType InTy,
+                      TreePattern &TP) {
+    return Types[ResNo].MergeInTypeInfo(EEVT::TypeSet(InTy, TP), TP);
+  }
+  
+  /// ContainsUnresolvedType - Return true if this tree contains any
+  /// unresolved types.
+  bool ContainsUnresolvedType() const {
+    for (unsigned i = 0, e = Types.size(); i != e; ++i)
+      if (!Types[i].isConcrete()) return true;
+    
+    for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+      if (getChild(i)->ContainsUnresolvedType()) return true;
+    return false;
+  }
+  
+  /// canPatternMatch - If it is impossible for this pattern to match on this
+  /// target, fill in Reason and return false.  Otherwise, return true.
+  bool canPatternMatch(std::string &Reason, const CodeGenDAGPatterns &CDP);
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const TreePatternNode &TPN) {
+  TPN.print(OS);
+  return OS;
+}
+  
+
+/// TreePattern - Represent a pattern, used for instructions, pattern
+/// fragments, etc.
+///
+class TreePattern {
+  /// Trees - The list of pattern trees which corresponds to this pattern.
+  /// Note that PatFrag's only have a single tree.
+  ///
+  std::vector<TreePatternNode*> Trees;
+  
+  /// NamedNodes - This is all of the nodes that have names in the trees in this
+  /// pattern.
+  StringMap<SmallVector<TreePatternNode*,1> > NamedNodes;
+  
+  /// TheRecord - The actual TableGen record corresponding to this pattern.
+  ///
+  Record *TheRecord;
+    
+  /// Args - This is a list of all of the arguments to this pattern (for
+  /// PatFrag patterns), which are the 'node' markers in this pattern.
+  std::vector<std::string> Args;
+  
+  /// CDP - the top-level object coordinating this madness.
+  ///
+  CodeGenDAGPatterns &CDP;
+
+  /// isInputPattern - True if this is an input pattern, something to match.
+  /// False if this is an output pattern, something to emit.
+  bool isInputPattern;
+public:
+    
+  /// TreePattern constructor - Parse the specified DagInits into the
+  /// current record.
+  TreePattern(Record *TheRec, ListInit *RawPat, bool isInput,
+              CodeGenDAGPatterns &ise);
+  TreePattern(Record *TheRec, DagInit *Pat, bool isInput,
+              CodeGenDAGPatterns &ise);
+  TreePattern(Record *TheRec, TreePatternNode *Pat, bool isInput,
+              CodeGenDAGPatterns &ise);
+      
+  /// getTrees - Return the tree patterns which corresponds to this pattern.
+  ///
+  const std::vector<TreePatternNode*> &getTrees() const { return Trees; }
+  unsigned getNumTrees() const { return Trees.size(); }
+  TreePatternNode *getTree(unsigned i) const { return Trees[i]; }
+  TreePatternNode *getOnlyTree() const {
+    assert(Trees.size() == 1 && "Doesn't have exactly one pattern!");
+    return Trees[0];
+  }
+  
+  const StringMap<SmallVector<TreePatternNode*,1> > &getNamedNodesMap() {
+    if (NamedNodes.empty())
+      ComputeNamedNodes();
+    return NamedNodes;
+  }
+      
+  /// getRecord - Return the actual TableGen record corresponding to this
+  /// pattern.
+  ///
+  Record *getRecord() const { return TheRecord; }
+  
+  unsigned getNumArgs() const { return Args.size(); }
+  const std::string &getArgName(unsigned i) const {
+    assert(i < Args.size() && "Argument reference out of range!");
+    return Args[i];
+  }
+  std::vector<std::string> &getArgList() { return Args; }
+  
+  CodeGenDAGPatterns &getDAGPatterns() const { return CDP; }
+
+  /// InlinePatternFragments - If this pattern refers to any pattern
+  /// fragments, inline them into place, giving us a pattern without any
+  /// PatFrag references.
+  void InlinePatternFragments() {
+    for (unsigned i = 0, e = Trees.size(); i != e; ++i)
+      Trees[i] = Trees[i]->InlinePatternFragments(*this);
+  }
+  
+  /// InferAllTypes - Infer/propagate as many types throughout the expression
+  /// patterns as possible.  Return true if all types are inferred, false
+  /// otherwise.  Throw an exception if a type contradiction is found.
+  bool InferAllTypes(const StringMap<SmallVector<TreePatternNode*,1> >
+                          *NamedTypes=0);
+  
+  /// error - Throw an exception, prefixing it with information about this
+  /// pattern.
+  void error(const std::string &Msg) const;
+  
+  void print(raw_ostream &OS) const;
+  void dump() const;
+  
+private:
+  TreePatternNode *ParseTreePattern(Init *DI, StringRef OpName);
+  void ComputeNamedNodes();
+  void ComputeNamedNodes(TreePatternNode *N);
+};
+
+/// DAGDefaultOperand - One of these is created for each PredicateOperand
+/// or OptionalDefOperand that has a set ExecuteAlways / DefaultOps field.
+struct DAGDefaultOperand {
+  std::vector<TreePatternNode*> DefaultOps;
+};
+
+class DAGInstruction {
+  TreePattern *Pattern;
+  std::vector<Record*> Results;
+  std::vector<Record*> Operands;
+  std::vector<Record*> ImpResults;
+  TreePatternNode *ResultPattern;
+public:
+  DAGInstruction(TreePattern *TP,
+                 const std::vector<Record*> &results,
+                 const std::vector<Record*> &operands,
+                 const std::vector<Record*> &impresults)
+    : Pattern(TP), Results(results), Operands(operands), 
+      ImpResults(impresults), ResultPattern(0) {}
+
+  const TreePattern *getPattern() const { return Pattern; }
+  unsigned getNumResults() const { return Results.size(); }
+  unsigned getNumOperands() const { return Operands.size(); }
+  unsigned getNumImpResults() const { return ImpResults.size(); }
+  const std::vector<Record*>& getImpResults() const { return ImpResults; }
+  
+  void setResultPattern(TreePatternNode *R) { ResultPattern = R; }
+  
+  Record *getResult(unsigned RN) const {
+    assert(RN < Results.size());
+    return Results[RN];
+  }
+  
+  Record *getOperand(unsigned ON) const {
+    assert(ON < Operands.size());
+    return Operands[ON];
+  }
+
+  Record *getImpResult(unsigned RN) const {
+    assert(RN < ImpResults.size());
+    return ImpResults[RN];
+  }
+  
+  TreePatternNode *getResultPattern() const { return ResultPattern; }
+};
+  
+/// PatternToMatch - Used by CodeGenDAGPatterns to keep tab of patterns
+/// processed to produce isel.
+class PatternToMatch {
+public:
+  PatternToMatch(ListInit *preds,
+                 TreePatternNode *src, TreePatternNode *dst,
+                 const std::vector<Record*> &dstregs,
+                 unsigned complexity, unsigned uid)
+    : Predicates(preds), SrcPattern(src), DstPattern(dst),
+      Dstregs(dstregs), AddedComplexity(complexity), ID(uid) {}
+
+  ListInit        *Predicates;  // Top level predicate conditions to match.
+  TreePatternNode *SrcPattern;  // Source pattern to match.
+  TreePatternNode *DstPattern;  // Resulting pattern.
+  std::vector<Record*> Dstregs; // Physical register defs being matched.
+  unsigned         AddedComplexity; // Add to matching pattern complexity.
+  unsigned         ID;          // Unique ID for the record.
+
+  ListInit        *getPredicates() const { return Predicates; }
+  TreePatternNode *getSrcPattern() const { return SrcPattern; }
+  TreePatternNode *getDstPattern() const { return DstPattern; }
+  const std::vector<Record*> &getDstRegs() const { return Dstregs; }
+  unsigned         getAddedComplexity() const { return AddedComplexity; }
+
+  std::string getPredicateCheck() const;
+  
+  /// Compute the complexity metric for the input pattern.  This roughly
+  /// corresponds to the number of nodes that are covered.
+  unsigned getPatternComplexity(const CodeGenDAGPatterns &CGP) const;
+};
+
+// Deterministic comparison of Record*.
+struct RecordPtrCmp {
+  bool operator()(const Record *LHS, const Record *RHS) const;
+};
+  
+class CodeGenDAGPatterns {
+  RecordKeeper &Records;
+  CodeGenTarget Target;
+  std::vector<CodeGenIntrinsic> Intrinsics;
+  std::vector<CodeGenIntrinsic> TgtIntrinsics;
+  
+  std::map<Record*, SDNodeInfo, RecordPtrCmp> SDNodes;
+  std::map<Record*, std::pair<Record*, std::string>, RecordPtrCmp> SDNodeXForms;
+  std::map<Record*, ComplexPattern, RecordPtrCmp> ComplexPatterns;
+  std::map<Record*, TreePattern*, RecordPtrCmp> PatternFragments;
+  std::map<Record*, DAGDefaultOperand, RecordPtrCmp> DefaultOperands;
+  std::map<Record*, DAGInstruction, RecordPtrCmp> Instructions;
+  
+  // Specific SDNode definitions:
+  Record *intrinsic_void_sdnode;
+  Record *intrinsic_w_chain_sdnode, *intrinsic_wo_chain_sdnode;
+  
+  /// PatternsToMatch - All of the things we are matching on the DAG.  The first
+  /// value is the pattern to match, the second pattern is the result to
+  /// emit.
+  std::vector<PatternToMatch> PatternsToMatch;
+public:
+  CodeGenDAGPatterns(RecordKeeper &R); 
+  ~CodeGenDAGPatterns();
+  
+  CodeGenTarget &getTargetInfo() { return Target; }
+  const CodeGenTarget &getTargetInfo() const { return Target; }
+  
+  Record *getSDNodeNamed(const std::string &Name) const;
+  
+  const SDNodeInfo &getSDNodeInfo(Record *R) const {
+    assert(SDNodes.count(R) && "Unknown node!");
+    return SDNodes.find(R)->second;
+  }
+  
+  // Node transformation lookups.
+  typedef std::pair<Record*, std::string> NodeXForm;
+  const NodeXForm &getSDNodeTransform(Record *R) const {
+    assert(SDNodeXForms.count(R) && "Invalid transform!");
+    return SDNodeXForms.find(R)->second;
+  }
+  
+  typedef std::map<Record*, NodeXForm, RecordPtrCmp>::const_iterator
+          nx_iterator;
+  nx_iterator nx_begin() const { return SDNodeXForms.begin(); }
+  nx_iterator nx_end() const { return SDNodeXForms.end(); }
+
+  
+  const ComplexPattern &getComplexPattern(Record *R) const {
+    assert(ComplexPatterns.count(R) && "Unknown addressing mode!");
+    return ComplexPatterns.find(R)->second;
+  }
+  
+  const CodeGenIntrinsic &getIntrinsic(Record *R) const {
+    for (unsigned i = 0, e = Intrinsics.size(); i != e; ++i)
+      if (Intrinsics[i].TheDef == R) return Intrinsics[i];
+    for (unsigned i = 0, e = TgtIntrinsics.size(); i != e; ++i)
+      if (TgtIntrinsics[i].TheDef == R) return TgtIntrinsics[i];
+    assert(0 && "Unknown intrinsic!");
+    abort();
+  }
+  
+  const CodeGenIntrinsic &getIntrinsicInfo(unsigned IID) const {
+    if (IID-1 < Intrinsics.size())
+      return Intrinsics[IID-1];
+    if (IID-Intrinsics.size()-1 < TgtIntrinsics.size())
+      return TgtIntrinsics[IID-Intrinsics.size()-1];
+    assert(0 && "Bad intrinsic ID!");
+    abort();
+  }
+  
+  unsigned getIntrinsicID(Record *R) const {
+    for (unsigned i = 0, e = Intrinsics.size(); i != e; ++i)
+      if (Intrinsics[i].TheDef == R) return i;
+    for (unsigned i = 0, e = TgtIntrinsics.size(); i != e; ++i)
+      if (TgtIntrinsics[i].TheDef == R) return i + Intrinsics.size();
+    assert(0 && "Unknown intrinsic!");
+    abort();
+  }
+  
+  const DAGDefaultOperand &getDefaultOperand(Record *R) const {
+    assert(DefaultOperands.count(R) &&"Isn't an analyzed default operand!");
+    return DefaultOperands.find(R)->second;
+  }
+  
+  // Pattern Fragment information.
+  TreePattern *getPatternFragment(Record *R) const {
+    assert(PatternFragments.count(R) && "Invalid pattern fragment request!");
+    return PatternFragments.find(R)->second;
+  }
+  TreePattern *getPatternFragmentIfRead(Record *R) const {
+    if (!PatternFragments.count(R)) return 0;
+    return PatternFragments.find(R)->second;
+  }
+  
+  typedef std::map<Record*, TreePattern*, RecordPtrCmp>::const_iterator
+          pf_iterator;
+  pf_iterator pf_begin() const { return PatternFragments.begin(); }
+  pf_iterator pf_end() const { return PatternFragments.end(); }
+
+  // Patterns to match information.
+  typedef std::vector<PatternToMatch>::const_iterator ptm_iterator;
+  ptm_iterator ptm_begin() const { return PatternsToMatch.begin(); }
+  ptm_iterator ptm_end() const { return PatternsToMatch.end(); }
+  
+  
+  
+  const DAGInstruction &getInstruction(Record *R) const {
+    assert(Instructions.count(R) && "Unknown instruction!");
+    return Instructions.find(R)->second;
+  }
+  
+  Record *get_intrinsic_void_sdnode() const {
+    return intrinsic_void_sdnode;
+  }
+  Record *get_intrinsic_w_chain_sdnode() const {
+    return intrinsic_w_chain_sdnode;
+  }
+  Record *get_intrinsic_wo_chain_sdnode() const {
+    return intrinsic_wo_chain_sdnode;
+  }
+  
+  bool hasTargetIntrinsics() { return !TgtIntrinsics.empty(); }
+
+private:
+  void ParseNodeInfo();
+  void ParseNodeTransforms();
+  void ParseComplexPatterns();
+  void ParsePatternFragments();
+  void ParseDefaultOperands();
+  void ParseInstructions();
+  void ParsePatterns();
+  void InferInstructionFlags();
+  void GenerateVariants();
+  
+  void AddPatternToMatch(const TreePattern *Pattern, const PatternToMatch &PTM);
+  void FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
+                                   std::map<std::string,
+                                   TreePatternNode*> &InstInputs,
+                                   std::map<std::string,
+                                   TreePatternNode*> &InstResults,
+                                   std::vector<Record*> &InstImpResults);
+};
+} // end namespace llvm
+
+#endif
diff --git a/src/LLVM/utils/TableGen/CodeGenInstruction.cpp b/src/LLVM/utils/TableGen/CodeGenInstruction.cpp
new file mode 100644
index 0000000..01a1fe1
--- /dev/null
+++ b/src/LLVM/utils/TableGen/CodeGenInstruction.cpp
@@ -0,0 +1,306 @@
+//===- CodeGenInstruction.cpp - CodeGen Instruction Class Wrapper ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the CodeGenInstruction class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenInstruction.h"
+#include "CodeGenTarget.h"
+#include "Record.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/STLExtras.h"
+#include <set>
+using namespace llvm;
+
+static void ParseConstraint(const std::string &CStr, CodeGenInstruction *I) {
+  // EARLY_CLOBBER: @early $reg
+  std::string::size_type wpos = CStr.find_first_of(" \t");
+  std::string::size_type start = CStr.find_first_not_of(" \t");
+  std::string Tok = CStr.substr(start, wpos - start);
+  if (Tok == "@earlyclobber") {
+    std::string Name = CStr.substr(wpos+1);
+    wpos = Name.find_first_not_of(" \t");
+    if (wpos == std::string::npos)
+      throw "Illegal format for @earlyclobber constraint: '" + CStr + "'";
+    Name = Name.substr(wpos);
+    std::pair<unsigned,unsigned> Op =
+      I->ParseOperandName(Name, false);
+
+    // Build the string for the operand
+    if (!I->OperandList[Op.first].Constraints[Op.second].isNone())
+      throw "Operand '" + Name + "' cannot have multiple constraints!";
+    I->OperandList[Op.first].Constraints[Op.second] =
+      CodeGenInstruction::ConstraintInfo::getEarlyClobber();
+    return;
+  }
+
+  // Only other constraint is "TIED_TO" for now.
+  std::string::size_type pos = CStr.find_first_of('=');
+  assert(pos != std::string::npos && "Unrecognized constraint");
+  start = CStr.find_first_not_of(" \t");
+  std::string Name = CStr.substr(start, pos - start);
+
+  // TIED_TO: $src1 = $dst
+  wpos = Name.find_first_of(" \t");
+  if (wpos == std::string::npos)
+    throw "Illegal format for tied-to constraint: '" + CStr + "'";
+  std::string DestOpName = Name.substr(0, wpos);
+  std::pair<unsigned,unsigned> DestOp = I->ParseOperandName(DestOpName, false);
+
+  Name = CStr.substr(pos+1);
+  wpos = Name.find_first_not_of(" \t");
+  if (wpos == std::string::npos)
+    throw "Illegal format for tied-to constraint: '" + CStr + "'";
+
+  std::pair<unsigned,unsigned> SrcOp =
+  I->ParseOperandName(Name.substr(wpos), false);
+  if (SrcOp > DestOp)
+    throw "Illegal tied-to operand constraint '" + CStr + "'";
+
+
+  unsigned FlatOpNo = I->getFlattenedOperandNumber(SrcOp);
+
+  if (!I->OperandList[DestOp.first].Constraints[DestOp.second].isNone())
+    throw "Operand '" + DestOpName + "' cannot have multiple constraints!";
+  I->OperandList[DestOp.first].Constraints[DestOp.second] =
+    CodeGenInstruction::ConstraintInfo::getTied(FlatOpNo);
+}
+
+static void ParseConstraints(const std::string &CStr, CodeGenInstruction *I) {
+  // Make sure the constraints list for each operand is large enough to hold
+  // constraint info, even if none is present.
+  for (unsigned i = 0, e = I->OperandList.size(); i != e; ++i)
+    I->OperandList[i].Constraints.resize(I->OperandList[i].MINumOperands);
+
+  if (CStr.empty()) return;
+
+  const std::string delims(",");
+  std::string::size_type bidx, eidx;
+
+  bidx = CStr.find_first_not_of(delims);
+  while (bidx != std::string::npos) {
+    eidx = CStr.find_first_of(delims, bidx);
+    if (eidx == std::string::npos)
+      eidx = CStr.length();
+
+    ParseConstraint(CStr.substr(bidx, eidx - bidx), I);
+    bidx = CStr.find_first_not_of(delims, eidx);
+  }
+}
+
+CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
+  : TheDef(R), AsmString(AsmStr) {
+  Namespace = R->getValueAsString("Namespace");
+
+  isReturn     = R->getValueAsBit("isReturn");
+  isBranch     = R->getValueAsBit("isBranch");
+  isIndirectBranch = R->getValueAsBit("isIndirectBranch");
+  isCompare    = R->getValueAsBit("isCompare");
+  isBarrier    = R->getValueAsBit("isBarrier");
+  isCall       = R->getValueAsBit("isCall");
+  canFoldAsLoad = R->getValueAsBit("canFoldAsLoad");
+  mayLoad      = R->getValueAsBit("mayLoad");
+  mayStore     = R->getValueAsBit("mayStore");
+  isPredicable = R->getValueAsBit("isPredicable");
+  isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress");
+  isCommutable = R->getValueAsBit("isCommutable");
+  isTerminator = R->getValueAsBit("isTerminator");
+  isReMaterializable = R->getValueAsBit("isReMaterializable");
+  hasDelaySlot = R->getValueAsBit("hasDelaySlot");
+  usesCustomInserter = R->getValueAsBit("usesCustomInserter");
+  hasCtrlDep   = R->getValueAsBit("hasCtrlDep");
+  isNotDuplicable = R->getValueAsBit("isNotDuplicable");
+  hasSideEffects = R->getValueAsBit("hasSideEffects");
+  neverHasSideEffects = R->getValueAsBit("neverHasSideEffects");
+  isAsCheapAsAMove = R->getValueAsBit("isAsCheapAsAMove");
+  hasExtraSrcRegAllocReq = R->getValueAsBit("hasExtraSrcRegAllocReq");
+  hasExtraDefRegAllocReq = R->getValueAsBit("hasExtraDefRegAllocReq");
+  hasOptionalDef = false;
+  isVariadic = false;
+  ImplicitDefs = R->getValueAsListOfDefs("Defs");
+  ImplicitUses = R->getValueAsListOfDefs("Uses");
+
+  if (neverHasSideEffects + hasSideEffects > 1)
+    throw R->getName() + ": multiple conflicting side-effect flags set!";
+
+  DagInit *OutDI = R->getValueAsDag("OutOperandList");
+
+  if (DefInit *Init = dynamic_cast<DefInit*>(OutDI->getOperator())) {
+    if (Init->getDef()->getName() != "outs")
+      throw R->getName() + ": invalid def name for output list: use 'outs'";
+  } else
+    throw R->getName() + ": invalid output list: use 'outs'";
+    
+  NumDefs = OutDI->getNumArgs();
+    
+  DagInit *InDI = R->getValueAsDag("InOperandList");
+  if (DefInit *Init = dynamic_cast<DefInit*>(InDI->getOperator())) {
+    if (Init->getDef()->getName() != "ins")
+      throw R->getName() + ": invalid def name for input list: use 'ins'";
+  } else
+    throw R->getName() + ": invalid input list: use 'ins'";
+    
+  unsigned MIOperandNo = 0;
+  std::set<std::string> OperandNames;
+  for (unsigned i = 0, e = InDI->getNumArgs()+OutDI->getNumArgs(); i != e; ++i){
+    Init *ArgInit;
+    std::string ArgName;
+    if (i < NumDefs) {
+      ArgInit = OutDI->getArg(i);
+      ArgName = OutDI->getArgName(i);
+    } else {
+      ArgInit = InDI->getArg(i-NumDefs);
+      ArgName = InDI->getArgName(i-NumDefs);
+    }
+    
+    DefInit *Arg = dynamic_cast<DefInit*>(ArgInit);
+    if (!Arg)
+      throw "Illegal operand for the '" + R->getName() + "' instruction!";
+
+    Record *Rec = Arg->getDef();
+    std::string PrintMethod = "printOperand";
+    unsigned NumOps = 1;
+    DagInit *MIOpInfo = 0;
+    if (Rec->isSubClassOf("Operand")) {
+      PrintMethod = Rec->getValueAsString("PrintMethod");
+      MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
+
+      // Verify that MIOpInfo has an 'ops' root value.
+      if (!dynamic_cast<DefInit*>(MIOpInfo->getOperator()) ||
+          dynamic_cast<DefInit*>(MIOpInfo->getOperator())
+               ->getDef()->getName() != "ops")
+        throw "Bad value for MIOperandInfo in operand '" + Rec->getName() +
+              "'\n";
+
+      // If we have MIOpInfo, then we have #operands equal to number of entries
+      // in MIOperandInfo.
+      if (unsigned NumArgs = MIOpInfo->getNumArgs())
+        NumOps = NumArgs;
+
+      if (Rec->isSubClassOf("PredicateOperand"))
+        isPredicable = true;
+      else if (Rec->isSubClassOf("OptionalDefOperand"))
+        hasOptionalDef = true;
+    } else if (Rec->getName() == "variable_ops") {
+      isVariadic = true;
+      continue;
+    } else if (!Rec->isSubClassOf("RegisterClass") &&
+               Rec->getName() != "ptr_rc" && Rec->getName() != "unknown")
+      throw "Unknown operand class '" + Rec->getName() +
+            "' in '" + R->getName() + "' instruction!";
+
+    // Check that the operand has a name and that it's unique.
+    if (ArgName.empty())
+      throw "In instruction '" + R->getName() + "', operand #" + utostr(i) +
+        " has no name!";
+    if (!OperandNames.insert(ArgName).second)
+      throw "In instruction '" + R->getName() + "', operand #" + utostr(i) +
+        " has the same name as a previous operand!";
+
+    OperandList.push_back(OperandInfo(Rec, ArgName, PrintMethod,
+                                      MIOperandNo, NumOps, MIOpInfo));
+    MIOperandNo += NumOps;
+  }
+
+  // Parse Constraints.
+  ParseConstraints(R->getValueAsString("Constraints"), this);
+
+  // Parse the DisableEncoding field.
+  std::string DisableEncoding = R->getValueAsString("DisableEncoding");
+  while (1) {
+    std::string OpName;
+    tie(OpName, DisableEncoding) = getToken(DisableEncoding, " ,\t");
+    if (OpName.empty()) break;
+
+    // Figure out which operand this is.
+    std::pair<unsigned,unsigned> Op = ParseOperandName(OpName, false);
+
+    // Mark the operand as not-to-be encoded.
+    if (Op.second >= OperandList[Op.first].DoNotEncode.size())
+      OperandList[Op.first].DoNotEncode.resize(Op.second+1);
+    OperandList[Op.first].DoNotEncode[Op.second] = true;
+  }
+}
+
+/// getOperandNamed - Return the index of the operand with the specified
+/// non-empty name.  If the instruction does not have an operand with the
+/// specified name, throw an exception.
+///
+unsigned CodeGenInstruction::getOperandNamed(const std::string &Name) const {
+  assert(!Name.empty() && "Cannot search for operand with no name!");
+  for (unsigned i = 0, e = OperandList.size(); i != e; ++i)
+    if (OperandList[i].Name == Name) return i;
+  throw "Instruction '" + TheDef->getName() +
+        "' does not have an operand named '$" + Name + "'!";
+}
+
+std::pair<unsigned,unsigned>
+CodeGenInstruction::ParseOperandName(const std::string &Op,
+                                     bool AllowWholeOp) {
+  if (Op.empty() || Op[0] != '$')
+    throw TheDef->getName() + ": Illegal operand name: '" + Op + "'";
+
+  std::string OpName = Op.substr(1);
+  std::string SubOpName;
+
+  // Check to see if this is $foo.bar.
+  std::string::size_type DotIdx = OpName.find_first_of(".");
+  if (DotIdx != std::string::npos) {
+    SubOpName = OpName.substr(DotIdx+1);
+    if (SubOpName.empty())
+      throw TheDef->getName() + ": illegal empty suboperand name in '" +Op +"'";
+    OpName = OpName.substr(0, DotIdx);
+  }
+
+  unsigned OpIdx = getOperandNamed(OpName);
+
+  if (SubOpName.empty()) {  // If no suboperand name was specified:
+    // If one was needed, throw.
+    if (OperandList[OpIdx].MINumOperands > 1 && !AllowWholeOp &&
+        SubOpName.empty())
+      throw TheDef->getName() + ": Illegal to refer to"
+            " whole operand part of complex operand '" + Op + "'";
+
+    // Otherwise, return the operand.
+    return std::make_pair(OpIdx, 0U);
+  }
+
+  // Find the suboperand number involved.
+  DagInit *MIOpInfo = OperandList[OpIdx].MIOperandInfo;
+  if (MIOpInfo == 0)
+    throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'";
+
+  // Find the operand with the right name.
+  for (unsigned i = 0, e = MIOpInfo->getNumArgs(); i != e; ++i)
+    if (MIOpInfo->getArgName(i) == SubOpName)
+      return std::make_pair(OpIdx, i);
+
+  // Otherwise, didn't find it!
+  throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'";
+}
+
+
+/// HasOneImplicitDefWithKnownVT - If the instruction has at least one
+/// implicit def and it has a known VT, return the VT, otherwise return
+/// MVT::Other.
+MVT::SimpleValueType CodeGenInstruction::
+HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const {
+  if (ImplicitDefs.empty()) return MVT::Other;
+  
+  // Check to see if the first implicit def has a resolvable type.
+  Record *FirstImplicitDef = ImplicitDefs[0];
+  assert(FirstImplicitDef->isSubClassOf("Register"));
+  const std::vector<MVT::SimpleValueType> &RegVTs = 
+    TargetInfo.getRegisterVTs(FirstImplicitDef);
+  if (RegVTs.size() == 1)
+    return RegVTs[0];
+  return MVT::Other;
+}
+
diff --git a/src/LLVM/utils/TableGen/CodeGenInstruction.h b/src/LLVM/utils/TableGen/CodeGenInstruction.h
new file mode 100644
index 0000000..b02d0d3
--- /dev/null
+++ b/src/LLVM/utils/TableGen/CodeGenInstruction.h
@@ -0,0 +1,197 @@
+//===- CodeGenInstruction.h - Instruction Class Wrapper ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a wrapper class for the 'Instruction' TableGen class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CODEGEN_INSTRUCTION_H
+#define CODEGEN_INSTRUCTION_H
+
+#include "llvm/CodeGen/ValueTypes.h"
+#include <string>
+#include <vector>
+#include <utility>
+
+namespace llvm {
+  class Record;
+  class DagInit;
+  class CodeGenTarget;
+
+  class CodeGenInstruction {
+  public:
+    Record *TheDef;            // The actual record defining this instruction.
+    std::string Namespace;     // The namespace the instruction is in.
+
+    /// AsmString - The format string used to emit a .s file for the
+    /// instruction.
+    std::string AsmString;
+    
+    class ConstraintInfo {
+      enum { None, EarlyClobber, Tied } Kind;
+      unsigned OtherTiedOperand;
+    public:
+      ConstraintInfo() : Kind(None) {}
+
+      static ConstraintInfo getEarlyClobber() {
+        ConstraintInfo I;
+        I.Kind = EarlyClobber;
+        I.OtherTiedOperand = 0;
+        return I;
+      }
+      
+      static ConstraintInfo getTied(unsigned Op) {
+        ConstraintInfo I;
+        I.Kind = Tied;
+        I.OtherTiedOperand = Op;
+        return I;
+      }
+      
+      bool isNone() const { return Kind == None; }
+      bool isEarlyClobber() const { return Kind == EarlyClobber; }
+      bool isTied() const { return Kind == Tied; }
+      
+      unsigned getTiedOperand() const {
+        assert(isTied());
+        return OtherTiedOperand;
+      }
+    };
+    
+    /// OperandInfo - The information we keep track of for each operand in the
+    /// operand list for a tablegen instruction.
+    struct OperandInfo {
+      /// Rec - The definition this operand is declared as.
+      ///
+      Record *Rec;
+
+      /// Name - If this operand was assigned a symbolic name, this is it,
+      /// otherwise, it's empty.
+      std::string Name;
+
+      /// PrinterMethodName - The method used to print operands of this type in
+      /// the asmprinter.
+      std::string PrinterMethodName;
+
+      /// MIOperandNo - Currently (this is meant to be phased out), some logical
+      /// operands correspond to multiple MachineInstr operands.  In the X86
+      /// target for example, one address operand is represented as 4
+      /// MachineOperands.  Because of this, the operand number in the
+      /// OperandList may not match the MachineInstr operand num.  Until it
+      /// does, this contains the MI operand index of this operand.
+      unsigned MIOperandNo;
+      unsigned MINumOperands;   // The number of operands.
+
+      /// DoNotEncode - Bools are set to true in this vector for each operand in
+      /// the DisableEncoding list.  These should not be emitted by the code
+      /// emitter.
+      std::vector<bool> DoNotEncode;
+      
+      /// MIOperandInfo - Default MI operand type. Note an operand may be made
+      /// up of multiple MI operands.
+      DagInit *MIOperandInfo;
+      
+      /// Constraint info for this operand.  This operand can have pieces, so we
+      /// track constraint info for each.
+      std::vector<ConstraintInfo> Constraints;
+
+      OperandInfo(Record *R, const std::string &N, const std::string &PMN, 
+                  unsigned MION, unsigned MINO, DagInit *MIOI)
+        : Rec(R), Name(N), PrinterMethodName(PMN), MIOperandNo(MION),
+          MINumOperands(MINO), MIOperandInfo(MIOI) {}
+    };
+
+    /// NumDefs - Number of def operands declared, this is the number of
+    /// elements in the instruction's (outs) list.
+    ///
+    unsigned NumDefs;
+
+    /// OperandList - The list of declared operands, along with their declared
+    /// type (which is a record).
+    std::vector<OperandInfo> OperandList;
+
+    /// ImplicitDefs/ImplicitUses - These are lists of registers that are
+    /// implicitly defined and used by the instruction.
+    std::vector<Record*> ImplicitDefs, ImplicitUses;
+
+    // Various boolean values we track for the instruction.
+    bool isReturn;
+    bool isBranch;
+    bool isIndirectBranch;
+    bool isCompare;
+    bool isBarrier;
+    bool isCall;
+    bool canFoldAsLoad;
+    bool mayLoad, mayStore;
+    bool isPredicable;
+    bool isConvertibleToThreeAddress;
+    bool isCommutable;
+    bool isTerminator;
+    bool isReMaterializable;
+    bool hasDelaySlot;
+    bool usesCustomInserter;
+    bool isVariadic;
+    bool hasCtrlDep;
+    bool isNotDuplicable;
+    bool hasOptionalDef;
+    bool hasSideEffects;
+    bool neverHasSideEffects;
+    bool isAsCheapAsAMove;
+    bool hasExtraSrcRegAllocReq;
+    bool hasExtraDefRegAllocReq;
+    
+    /// ParseOperandName - Parse an operand name like "$foo" or "$foo.bar",
+    /// where $foo is a whole operand and $foo.bar refers to a suboperand.
+    /// This throws an exception if the name is invalid.  If AllowWholeOp is
+    /// true, references to operands with suboperands are allowed, otherwise
+    /// not.
+    std::pair<unsigned,unsigned> ParseOperandName(const std::string &Op,
+                                                  bool AllowWholeOp = true);
+    
+    /// getFlattenedOperandNumber - Flatten a operand/suboperand pair into a
+    /// flat machineinstr operand #.
+    unsigned getFlattenedOperandNumber(std::pair<unsigned,unsigned> Op) const {
+      return OperandList[Op.first].MIOperandNo + Op.second;
+    }
+    
+    /// getSubOperandNumber - Unflatten a operand number into an
+    /// operand/suboperand pair.
+    std::pair<unsigned,unsigned> getSubOperandNumber(unsigned Op) const {
+      for (unsigned i = 0; ; ++i) {
+        assert(i < OperandList.size() && "Invalid flat operand #");
+        if (OperandList[i].MIOperandNo+OperandList[i].MINumOperands > Op)
+          return std::make_pair(i, Op-OperandList[i].MIOperandNo);
+      }
+    }
+    
+    
+    /// isFlatOperandNotEmitted - Return true if the specified flat operand #
+    /// should not be emitted with the code emitter.
+    bool isFlatOperandNotEmitted(unsigned FlatOpNo) const {
+      std::pair<unsigned,unsigned> Op = getSubOperandNumber(FlatOpNo);
+      if (OperandList[Op.first].DoNotEncode.size() > Op.second)
+        return OperandList[Op.first].DoNotEncode[Op.second];
+      return false;
+    }
+
+    CodeGenInstruction(Record *R, const std::string &AsmStr);
+
+    /// getOperandNamed - Return the index of the operand with the specified
+    /// non-empty name.  If the instruction does not have an operand with the
+    /// specified name, throw an exception.
+    unsigned getOperandNamed(const std::string &Name) const;
+    
+    /// HasOneImplicitDefWithKnownVT - If the instruction has at least one
+    /// implicit def and it has a known VT, return the VT, otherwise return
+    /// MVT::Other.
+    MVT::SimpleValueType 
+      HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const;
+  };
+}
+
+#endif
diff --git a/src/LLVM/utils/TableGen/CodeGenIntrinsics.h b/src/LLVM/utils/TableGen/CodeGenIntrinsics.h
new file mode 100644
index 0000000..3208c0d
--- /dev/null
+++ b/src/LLVM/utils/TableGen/CodeGenIntrinsics.h
@@ -0,0 +1,87 @@
+//===- CodeGenIntrinsic.h - Intrinsic Class Wrapper ------------*- C++ -*--===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a wrapper class for the 'Intrinsic' TableGen class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CODEGEN_INTRINSIC_H
+#define CODEGEN_INTRINSIC_H
+
+#include <string>
+#include <vector>
+#include "llvm/CodeGen/ValueTypes.h"
+
+namespace llvm {
+  class Record;
+  class RecordKeeper;
+  class CodeGenTarget;
+
+  struct CodeGenIntrinsic {
+    Record *TheDef;            // The actual record defining this intrinsic.
+    std::string Name;          // The name of the LLVM function "llvm.bswap.i32"
+    std::string EnumName;      // The name of the enum "bswap_i32"
+    std::string GCCBuiltinName;// Name of the corresponding GCC builtin, or "".
+    std::string TargetPrefix;  // Target prefix, e.g. "ppc" for t-s intrinsics.
+
+    /// IntrinsicSignature - This structure holds the return values and
+    /// parameter values of an intrinsic. If the number of return values is > 1,
+    /// then the intrinsic implicitly returns a first-class aggregate. The
+    /// numbering of the types starts at 0 with the first return value and
+    /// continues from there through the parameter list. This is useful for
+    /// "matching" types.
+    struct IntrinsicSignature {
+      /// RetVTs - The MVT::SimpleValueType for each return type. Note that this
+      /// list is only populated when in the context of a target .td file. When
+      /// building Intrinsics.td, this isn't available, because we don't know
+      /// the target pointer size.
+      std::vector<MVT::SimpleValueType> RetVTs;
+
+      /// RetTypeDefs - The records for each return type.
+      std::vector<Record*> RetTypeDefs;
+
+      /// ParamVTs - The MVT::SimpleValueType for each parameter type. Note that
+      /// this list is only populated when in the context of a target .td file.
+      /// When building Intrinsics.td, this isn't available, because we don't
+      /// know the target pointer size.
+      std::vector<MVT::SimpleValueType> ParamVTs;
+
+      /// ParamTypeDefs - The records for each parameter type.
+      std::vector<Record*> ParamTypeDefs;
+    };
+
+    IntrinsicSignature IS;
+
+    // Memory mod/ref behavior of this intrinsic.
+    enum {
+      NoMem, ReadArgMem, ReadMem, ReadWriteArgMem, ReadWriteMem
+    } ModRef;
+
+    /// This is set to true if the intrinsic is overloaded by its argument
+    /// types.
+    bool isOverloaded;
+
+    /// isCommutative - True if the intrinsic is commutative.
+    bool isCommutative;
+    
+    enum ArgAttribute {
+      NoCapture
+    };
+    std::vector<std::pair<unsigned, ArgAttribute> > ArgumentAttributes;
+
+    CodeGenIntrinsic(Record *R);
+  };
+
+  /// LoadIntrinsics - Read all of the intrinsics defined in the specified
+  /// .td file.
+  std::vector<CodeGenIntrinsic> LoadIntrinsics(const RecordKeeper &RC,
+                                               bool TargetOnly);
+}
+
+#endif
diff --git a/src/LLVM/utils/TableGen/CodeGenRegisters.h b/src/LLVM/utils/TableGen/CodeGenRegisters.h
new file mode 100644
index 0000000..344f77f
--- /dev/null
+++ b/src/LLVM/utils/TableGen/CodeGenRegisters.h
@@ -0,0 +1,63 @@
+//===- CodeGenRegisters.h - Register and RegisterClass Info -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines structures to encapsulate information gleaned from the
+// target register and register class definitions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CODEGEN_REGISTERS_H
+#define CODEGEN_REGISTERS_H
+
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/ADT/DenseMap.h"
+#include <string>
+#include <vector>
+#include <cstdlib>
+
+namespace llvm {
+  class Record;
+
+  /// CodeGenRegister - Represents a register definition.
+  struct CodeGenRegister {
+    Record *TheDef;
+    const std::string &getName() const;
+    unsigned DeclaredSpillSize, DeclaredSpillAlignment;
+    CodeGenRegister(Record *R);
+  };
+
+
+  struct CodeGenRegisterClass {
+    Record *TheDef;
+    std::string Namespace;
+    std::vector<Record*> Elements;
+    std::vector<MVT::SimpleValueType> VTs;
+    unsigned SpillSize;
+    unsigned SpillAlignment;
+    int CopyCost;
+    // Map SubRegIndex -> RegisterClass
+    DenseMap<Record*,Record*> SubRegClasses;
+    std::string MethodProtos, MethodBodies;
+
+    const std::string &getName() const;
+    const std::vector<MVT::SimpleValueType> &getValueTypes() const {return VTs;}
+    unsigned getNumValueTypes() const { return VTs.size(); }
+    
+    MVT::SimpleValueType getValueTypeNum(unsigned VTNum) const {
+      if (VTNum < VTs.size())
+        return VTs[VTNum];
+      assert(0 && "VTNum greater than number of ValueTypes in RegClass!");
+      abort();
+    }
+
+    CodeGenRegisterClass(Record *R);
+  };
+}
+
+#endif
diff --git a/src/LLVM/utils/TableGen/CodeGenTarget.cpp b/src/LLVM/utils/TableGen/CodeGenTarget.cpp
new file mode 100644
index 0000000..cbfe2ad
--- /dev/null
+++ b/src/LLVM/utils/TableGen/CodeGenTarget.cpp
@@ -0,0 +1,568 @@
+//===- CodeGenTarget.cpp - CodeGen Target Class Wrapper -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class wraps target description classes used by the various code
+// generation TableGen backends.  This makes it easier to access the data and
+// provides a single place that needs to check it for validity.  All of these
+// classes throw exceptions on error conditions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenTarget.h"
+#include "CodeGenIntrinsics.h"
+#include "Record.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/CommandLine.h"
+#include <algorithm>
+using namespace llvm;
+
+static cl::opt<unsigned>
+AsmParserNum("asmparsernum", cl::init(0),
+             cl::desc("Make -gen-asm-parser emit assembly parser #N"));
+
+static cl::opt<unsigned>
+AsmWriterNum("asmwriternum", cl::init(0),
+             cl::desc("Make -gen-asm-writer emit assembly writer #N"));
+
+/// getValueType - Return the MVT::SimpleValueType that the specified TableGen
+/// record corresponds to.
+MVT::SimpleValueType llvm::getValueType(Record *Rec) {
+  return (MVT::SimpleValueType)Rec->getValueAsInt("Value");
+}
+
+std::string llvm::getName(MVT::SimpleValueType T) {
+  switch (T) {
+  case MVT::Other:   return "UNKNOWN";
+  case MVT::iPTR:    return "TLI.getPointerTy()";
+  case MVT::iPTRAny: return "TLI.getPointerTy()";
+  default: return getEnumName(T);
+  }
+}
+
+std::string llvm::getEnumName(MVT::SimpleValueType T) {
+  switch (T) {
+  case MVT::Other: return "MVT::Other";
+  case MVT::i1:    return "MVT::i1";
+  case MVT::i8:    return "MVT::i8";
+  case MVT::i16:   return "MVT::i16";
+  case MVT::i32:   return "MVT::i32";
+  case MVT::i64:   return "MVT::i64";
+  case MVT::i128:  return "MVT::i128";
+  case MVT::iAny:  return "MVT::iAny";
+  case MVT::fAny:  return "MVT::fAny";
+  case MVT::vAny:  return "MVT::vAny";
+  case MVT::f32:   return "MVT::f32";
+  case MVT::f64:   return "MVT::f64";
+  case MVT::f80:   return "MVT::f80";
+  case MVT::f128:  return "MVT::f128";
+  case MVT::ppcf128:  return "MVT::ppcf128";
+  case MVT::Flag:  return "MVT::Flag";
+  case MVT::isVoid:return "MVT::isVoid";
+  case MVT::v2i8:  return "MVT::v2i8";
+  case MVT::v4i8:  return "MVT::v4i8";
+  case MVT::v8i8:  return "MVT::v8i8";
+  case MVT::v16i8: return "MVT::v16i8";
+  case MVT::v32i8: return "MVT::v32i8";
+  case MVT::v2i16: return "MVT::v2i16";
+  case MVT::v4i16: return "MVT::v4i16";
+  case MVT::v8i16: return "MVT::v8i16";
+  case MVT::v16i16: return "MVT::v16i16";
+  case MVT::v2i32: return "MVT::v2i32";
+  case MVT::v4i32: return "MVT::v4i32";
+  case MVT::v8i32: return "MVT::v8i32";
+  case MVT::v1i64: return "MVT::v1i64";
+  case MVT::v2i64: return "MVT::v2i64";
+  case MVT::v4i64: return "MVT::v4i64";
+  case MVT::v8i64: return "MVT::v8i64";
+  case MVT::v2f32: return "MVT::v2f32";
+  case MVT::v4f32: return "MVT::v4f32";
+  case MVT::v8f32: return "MVT::v8f32";
+  case MVT::v2f64: return "MVT::v2f64";
+  case MVT::v4f64: return "MVT::v4f64";
+  case MVT::Metadata: return "MVT::Metadata";
+  case MVT::iPTR:  return "MVT::iPTR";
+  case MVT::iPTRAny:  return "MVT::iPTRAny";
+  default: assert(0 && "ILLEGAL VALUE TYPE!"); return "";
+  }
+}
+
+/// getQualifiedName - Return the name of the specified record, with a
+/// namespace qualifier if the record contains one.
+///
+std::string llvm::getQualifiedName(const Record *R) {
+  std::string Namespace = R->getValueAsString("Namespace");
+  if (Namespace.empty()) return R->getName();
+  return Namespace + "::" + R->getName();
+}
+
+
+
+
+/// getTarget - Return the current instance of the Target class.
+///
+CodeGenTarget::CodeGenTarget() {
+  std::vector<Record*> Targets = Records.getAllDerivedDefinitions("Target");
+  if (Targets.size() == 0)
+    throw std::string("ERROR: No 'Target' subclasses defined!");
+  if (Targets.size() != 1)
+    throw std::string("ERROR: Multiple subclasses of Target defined!");
+  TargetRec = Targets[0];
+}
+
+
+const std::string &CodeGenTarget::getName() const {
+  return TargetRec->getName();
+}
+
+std::string CodeGenTarget::getInstNamespace() const {
+  for (inst_iterator i = inst_begin(), e = inst_end(); i != e; ++i) {
+    // Make sure not to pick up "TargetOpcode" by accidentally getting
+    // the namespace off the PHI instruction or something.
+    if ((*i)->Namespace != "TargetOpcode")
+      return (*i)->Namespace;
+  }
+
+  return "";
+}
+
+Record *CodeGenTarget::getInstructionSet() const {
+  return TargetRec->getValueAsDef("InstructionSet");
+}
+
+
+/// getAsmParser - Return the AssemblyParser definition for this target.
+///
+Record *CodeGenTarget::getAsmParser() const {
+  std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyParsers");
+  if (AsmParserNum >= LI.size())
+    throw "Target does not have an AsmParser #" + utostr(AsmParserNum) + "!";
+  return LI[AsmParserNum];
+}
+
+/// getAsmWriter - Return the AssemblyWriter definition for this target.
+///
+Record *CodeGenTarget::getAsmWriter() const {
+  std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyWriters");
+  if (AsmWriterNum >= LI.size())
+    throw "Target does not have an AsmWriter #" + utostr(AsmWriterNum) + "!";
+  return LI[AsmWriterNum];
+}
+
+void CodeGenTarget::ReadRegisters() const {
+  std::vector<Record*> Regs = Records.getAllDerivedDefinitions("Register");
+  if (Regs.empty())
+    throw std::string("No 'Register' subclasses defined!");
+  std::sort(Regs.begin(), Regs.end(), LessRecord());
+
+  Registers.reserve(Regs.size());
+  Registers.assign(Regs.begin(), Regs.end());
+}
+
+CodeGenRegister::CodeGenRegister(Record *R) : TheDef(R) {
+  DeclaredSpillSize = R->getValueAsInt("SpillSize");
+  DeclaredSpillAlignment = R->getValueAsInt("SpillAlignment");
+}
+
+const std::string &CodeGenRegister::getName() const {
+  return TheDef->getName();
+}
+
+void CodeGenTarget::ReadSubRegIndices() const {
+  SubRegIndices = Records.getAllDerivedDefinitions("SubRegIndex");
+  std::sort(SubRegIndices.begin(), SubRegIndices.end(), LessRecord());
+}
+
+void CodeGenTarget::ReadRegisterClasses() const {
+  std::vector<Record*> RegClasses =
+    Records.getAllDerivedDefinitions("RegisterClass");
+  if (RegClasses.empty())
+    throw std::string("No 'RegisterClass' subclasses defined!");
+
+  RegisterClasses.reserve(RegClasses.size());
+  RegisterClasses.assign(RegClasses.begin(), RegClasses.end());
+}
+
+std::vector<MVT::SimpleValueType> CodeGenTarget::
+getRegisterVTs(Record *R) const {
+  std::vector<MVT::SimpleValueType> Result;
+  const std::vector<CodeGenRegisterClass> &RCs = getRegisterClasses();
+  for (unsigned i = 0, e = RCs.size(); i != e; ++i) {
+    const CodeGenRegisterClass &RC = RegisterClasses[i];
+    for (unsigned ei = 0, ee = RC.Elements.size(); ei != ee; ++ei) {
+      if (R == RC.Elements[ei]) {
+        const std::vector<MVT::SimpleValueType> &InVTs = RC.getValueTypes();
+        Result.insert(Result.end(), InVTs.begin(), InVTs.end());
+      }
+    }
+  }
+  
+  // Remove duplicates.
+  array_pod_sort(Result.begin(), Result.end());
+  Result.erase(std::unique(Result.begin(), Result.end()), Result.end());
+  return Result;
+}
+
+
+CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) {
+  // Rename anonymous register classes.
+  if (R->getName().size() > 9 && R->getName()[9] == '.') {
+    static unsigned AnonCounter = 0;
+    R->setName("AnonRegClass_"+utostr(AnonCounter++));
+  } 
+  
+  std::vector<Record*> TypeList = R->getValueAsListOfDefs("RegTypes");
+  for (unsigned i = 0, e = TypeList.size(); i != e; ++i) {
+    Record *Type = TypeList[i];
+    if (!Type->isSubClassOf("ValueType"))
+      throw "RegTypes list member '" + Type->getName() +
+        "' does not derive from the ValueType class!";
+    VTs.push_back(getValueType(Type));
+  }
+  assert(!VTs.empty() && "RegisterClass must contain at least one ValueType!");
+  
+  std::vector<Record*> RegList = R->getValueAsListOfDefs("MemberList");
+  for (unsigned i = 0, e = RegList.size(); i != e; ++i) {
+    Record *Reg = RegList[i];
+    if (!Reg->isSubClassOf("Register"))
+      throw "Register Class member '" + Reg->getName() +
+            "' does not derive from the Register class!";
+    Elements.push_back(Reg);
+  }
+
+  // SubRegClasses is a list<dag> containing (RC, subregindex, ...) dags.
+  ListInit *SRC = R->getValueAsListInit("SubRegClasses");
+  for (ListInit::const_iterator i = SRC->begin(), e = SRC->end(); i != e; ++i) {
+    DagInit *DAG = dynamic_cast<DagInit*>(*i);
+    if (!DAG) throw "SubRegClasses must contain DAGs";
+    DefInit *DAGOp = dynamic_cast<DefInit*>(DAG->getOperator());
+    Record *RCRec;
+    if (!DAGOp || !(RCRec = DAGOp->getDef())->isSubClassOf("RegisterClass"))
+      throw "Operator '" + DAG->getOperator()->getAsString() +
+        "' in SubRegClasses is not a RegisterClass";
+    // Iterate over args, all SubRegIndex instances.
+    for (DagInit::const_arg_iterator ai = DAG->arg_begin(), ae = DAG->arg_end();
+         ai != ae; ++ai) {
+      DefInit *Idx = dynamic_cast<DefInit*>(*ai);
+      Record *IdxRec;
+      if (!Idx || !(IdxRec = Idx->getDef())->isSubClassOf("SubRegIndex"))
+        throw "Argument '" + (*ai)->getAsString() +
+          "' in SubRegClasses is not a SubRegIndex";
+      if (!SubRegClasses.insert(std::make_pair(IdxRec, RCRec)).second)
+        throw "SubRegIndex '" + IdxRec->getName() + "' mentioned twice";
+    }
+  }
+
+  // Allow targets to override the size in bits of the RegisterClass.
+  unsigned Size = R->getValueAsInt("Size");
+
+  Namespace = R->getValueAsString("Namespace");
+  SpillSize = Size ? Size : EVT(VTs[0]).getSizeInBits();
+  SpillAlignment = R->getValueAsInt("Alignment");
+  CopyCost = R->getValueAsInt("CopyCost");
+  MethodBodies = R->getValueAsCode("MethodBodies");
+  MethodProtos = R->getValueAsCode("MethodProtos");
+}
+
+const std::string &CodeGenRegisterClass::getName() const {
+  return TheDef->getName();
+}
+
+void CodeGenTarget::ReadLegalValueTypes() const {
+  const std::vector<CodeGenRegisterClass> &RCs = getRegisterClasses();
+  for (unsigned i = 0, e = RCs.size(); i != e; ++i)
+    for (unsigned ri = 0, re = RCs[i].VTs.size(); ri != re; ++ri)
+      LegalValueTypes.push_back(RCs[i].VTs[ri]);
+  
+  // Remove duplicates.
+  std::sort(LegalValueTypes.begin(), LegalValueTypes.end());
+  LegalValueTypes.erase(std::unique(LegalValueTypes.begin(),
+                                    LegalValueTypes.end()),
+                        LegalValueTypes.end());
+}
+
+
+void CodeGenTarget::ReadInstructions() const {
+  std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
+  if (Insts.size() <= 2)
+    throw std::string("No 'Instruction' subclasses defined!");
+
+  // Parse the instructions defined in the .td file.
+  std::string InstFormatName =
+    getAsmWriter()->getValueAsString("InstFormatName");
+
+  for (unsigned i = 0, e = Insts.size(); i != e; ++i) {
+    std::string AsmStr = Insts[i]->getValueAsString(InstFormatName);
+    Instructions[Insts[i]] = new CodeGenInstruction(Insts[i], AsmStr);
+  }
+}
+
+static const CodeGenInstruction *
+GetInstByName(const char *Name,
+              const DenseMap<const Record*, CodeGenInstruction*> &Insts) {
+  const Record *Rec = Records.getDef(Name);
+  
+  DenseMap<const Record*, CodeGenInstruction*>::const_iterator
+    I = Insts.find(Rec);
+  if (Rec == 0 || I == Insts.end())
+    throw std::string("Could not find '") + Name + "' instruction!";
+  return I->second;
+}
+
+namespace {
+/// SortInstByName - Sorting predicate to sort instructions by name.
+///
+struct SortInstByName {
+  bool operator()(const CodeGenInstruction *Rec1,
+                  const CodeGenInstruction *Rec2) const {
+    return Rec1->TheDef->getName() < Rec2->TheDef->getName();
+  }
+};
+}
+
+/// getInstructionsByEnumValue - Return all of the instructions defined by the
+/// target, ordered by their enum value.
+void CodeGenTarget::ComputeInstrsByEnum() const {
+  // The ordering here must match the ordering in TargetOpcodes.h.
+  const char *const FixedInstrs[] = {
+    "PHI",
+    "INLINEASM",
+    "PROLOG_LABEL",
+    "EH_LABEL",
+    "GC_LABEL",
+    "KILL",
+    "EXTRACT_SUBREG",
+    "INSERT_SUBREG",
+    "IMPLICIT_DEF",
+    "SUBREG_TO_REG",
+    "COPY_TO_REGCLASS",
+    "DBG_VALUE",
+    "REG_SEQUENCE",
+    "COPY",
+    0
+  };
+  const DenseMap<const Record*, CodeGenInstruction*> &Insts = getInstructions();
+  for (const char *const *p = FixedInstrs; *p; ++p) {
+    const CodeGenInstruction *Instr = GetInstByName(*p, Insts);
+    assert(Instr && "Missing target independent instruction");
+    assert(Instr->Namespace == "TargetOpcode" && "Bad namespace");
+    InstrsByEnum.push_back(Instr);
+  }
+  unsigned EndOfPredefines = InstrsByEnum.size();
+
+  for (DenseMap<const Record*, CodeGenInstruction*>::const_iterator
+       I = Insts.begin(), E = Insts.end(); I != E; ++I) {
+    const CodeGenInstruction *CGI = I->second;
+    if (CGI->Namespace != "TargetOpcode")
+      InstrsByEnum.push_back(CGI);
+  }
+
+  assert(InstrsByEnum.size() == Insts.size() && "Missing predefined instr");
+
+  // All of the instructions are now in random order based on the map iteration.
+  // Sort them by name.
+  std::sort(InstrsByEnum.begin()+EndOfPredefines, InstrsByEnum.end(),
+            SortInstByName());
+}
+
+
+/// isLittleEndianEncoding - Return whether this target encodes its instruction
+/// in little-endian format, i.e. bits laid out in the order [0..n]
+///
+bool CodeGenTarget::isLittleEndianEncoding() const {
+  return getInstructionSet()->getValueAsBit("isLittleEndianEncoding");
+}
+
+//===----------------------------------------------------------------------===//
+// ComplexPattern implementation
+//
+ComplexPattern::ComplexPattern(Record *R) {
+  Ty          = ::getValueType(R->getValueAsDef("Ty"));
+  NumOperands = R->getValueAsInt("NumOperands");
+  SelectFunc  = R->getValueAsString("SelectFunc");
+  RootNodes   = R->getValueAsListOfDefs("RootNodes");
+
+  // Parse the properties.
+  Properties = 0;
+  std::vector<Record*> PropList = R->getValueAsListOfDefs("Properties");
+  for (unsigned i = 0, e = PropList.size(); i != e; ++i)
+    if (PropList[i]->getName() == "SDNPHasChain") {
+      Properties |= 1 << SDNPHasChain;
+    } else if (PropList[i]->getName() == "SDNPOptInFlag") {
+      Properties |= 1 << SDNPOptInFlag;
+    } else if (PropList[i]->getName() == "SDNPMayStore") {
+      Properties |= 1 << SDNPMayStore;
+    } else if (PropList[i]->getName() == "SDNPMayLoad") {
+      Properties |= 1 << SDNPMayLoad;
+    } else if (PropList[i]->getName() == "SDNPSideEffect") {
+      Properties |= 1 << SDNPSideEffect;
+    } else if (PropList[i]->getName() == "SDNPMemOperand") {
+      Properties |= 1 << SDNPMemOperand;
+    } else if (PropList[i]->getName() == "SDNPVariadic") {
+      Properties |= 1 << SDNPVariadic;
+    } else {
+      errs() << "Unsupported SD Node property '" << PropList[i]->getName()
+             << "' on ComplexPattern '" << R->getName() << "'!\n";
+      exit(1);
+    }
+}
+
+//===----------------------------------------------------------------------===//
+// CodeGenIntrinsic Implementation
+//===----------------------------------------------------------------------===//
+
+std::vector<CodeGenIntrinsic> llvm::LoadIntrinsics(const RecordKeeper &RC,
+                                                   bool TargetOnly) {
+  std::vector<Record*> I = RC.getAllDerivedDefinitions("Intrinsic");
+  
+  std::vector<CodeGenIntrinsic> Result;
+
+  for (unsigned i = 0, e = I.size(); i != e; ++i) {
+    bool isTarget = I[i]->getValueAsBit("isTarget");
+    if (isTarget == TargetOnly)
+      Result.push_back(CodeGenIntrinsic(I[i]));
+  }
+  return Result;
+}
+
+CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
+  TheDef = R;
+  std::string DefName = R->getName();
+  ModRef = ReadWriteMem;
+  isOverloaded = false;
+  isCommutative = false;
+  
+  if (DefName.size() <= 4 || 
+      std::string(DefName.begin(), DefName.begin() + 4) != "int_")
+    throw "Intrinsic '" + DefName + "' does not start with 'int_'!";
+
+  EnumName = std::string(DefName.begin()+4, DefName.end());
+
+  if (R->getValue("GCCBuiltinName"))  // Ignore a missing GCCBuiltinName field.
+    GCCBuiltinName = R->getValueAsString("GCCBuiltinName");
+
+  TargetPrefix = R->getValueAsString("TargetPrefix");
+  Name = R->getValueAsString("LLVMName");
+
+  if (Name == "") {
+    // If an explicit name isn't specified, derive one from the DefName.
+    Name = "llvm.";
+
+    for (unsigned i = 0, e = EnumName.size(); i != e; ++i)
+      Name += (EnumName[i] == '_') ? '.' : EnumName[i];
+  } else {
+    // Verify it starts with "llvm.".
+    if (Name.size() <= 5 || 
+        std::string(Name.begin(), Name.begin() + 5) != "llvm.")
+      throw "Intrinsic '" + DefName + "'s name does not start with 'llvm.'!";
+  }
+  
+  // If TargetPrefix is specified, make sure that Name starts with
+  // "llvm.<targetprefix>.".
+  if (!TargetPrefix.empty()) {
+    if (Name.size() < 6+TargetPrefix.size() ||
+        std::string(Name.begin() + 5, Name.begin() + 6 + TargetPrefix.size())
+        != (TargetPrefix + "."))
+      throw "Intrinsic '" + DefName + "' does not start with 'llvm." +
+        TargetPrefix + ".'!";
+  }
+  
+  // Parse the list of return types.
+  std::vector<MVT::SimpleValueType> OverloadedVTs;
+  ListInit *TypeList = R->getValueAsListInit("RetTypes");
+  for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
+    Record *TyEl = TypeList->getElementAsRecord(i);
+    assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
+    MVT::SimpleValueType VT;
+    if (TyEl->isSubClassOf("LLVMMatchType")) {
+      unsigned MatchTy = TyEl->getValueAsInt("Number");
+      assert(MatchTy < OverloadedVTs.size() &&
+             "Invalid matching number!");
+      VT = OverloadedVTs[MatchTy];
+      // It only makes sense to use the extended and truncated vector element
+      // variants with iAny types; otherwise, if the intrinsic is not
+      // overloaded, all the types can be specified directly.
+      assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
+               !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
+              VT == MVT::iAny || VT == MVT::vAny) &&
+             "Expected iAny or vAny type");
+    } else {
+      VT = getValueType(TyEl->getValueAsDef("VT"));
+    }
+    if (EVT(VT).isOverloaded()) {
+      OverloadedVTs.push_back(VT);
+      isOverloaded = true;
+    }
+
+    // Reject invalid types.
+    if (VT == MVT::isVoid)
+      throw "Intrinsic '" + DefName + " has void in result type list!";
+    
+    IS.RetVTs.push_back(VT);
+    IS.RetTypeDefs.push_back(TyEl);
+  }
+  
+  // Parse the list of parameter types.
+  TypeList = R->getValueAsListInit("ParamTypes");
+  for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
+    Record *TyEl = TypeList->getElementAsRecord(i);
+    assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
+    MVT::SimpleValueType VT;
+    if (TyEl->isSubClassOf("LLVMMatchType")) {
+      unsigned MatchTy = TyEl->getValueAsInt("Number");
+      assert(MatchTy < OverloadedVTs.size() &&
+             "Invalid matching number!");
+      VT = OverloadedVTs[MatchTy];
+      // It only makes sense to use the extended and truncated vector element
+      // variants with iAny types; otherwise, if the intrinsic is not
+      // overloaded, all the types can be specified directly.
+      assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
+               !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
+              VT == MVT::iAny || VT == MVT::vAny) &&
+             "Expected iAny or vAny type");
+    } else
+      VT = getValueType(TyEl->getValueAsDef("VT"));
+    
+    if (EVT(VT).isOverloaded()) {
+      OverloadedVTs.push_back(VT);
+      isOverloaded = true;
+    }
+    
+    // Reject invalid types.
+    if (VT == MVT::isVoid && i != e-1 /*void at end means varargs*/)
+      throw "Intrinsic '" + DefName + " has void in result type list!";
+    
+    IS.ParamVTs.push_back(VT);
+    IS.ParamTypeDefs.push_back(TyEl);
+  }
+
+  // Parse the intrinsic properties.
+  ListInit *PropList = R->getValueAsListInit("Properties");
+  for (unsigned i = 0, e = PropList->getSize(); i != e; ++i) {
+    Record *Property = PropList->getElementAsRecord(i);
+    assert(Property->isSubClassOf("IntrinsicProperty") &&
+           "Expected a property!");
+    
+    if (Property->getName() == "IntrNoMem")
+      ModRef = NoMem;
+    else if (Property->getName() == "IntrReadArgMem")
+      ModRef = ReadArgMem;
+    else if (Property->getName() == "IntrReadMem")
+      ModRef = ReadMem;
+    else if (Property->getName() == "IntrReadWriteArgMem")
+      ModRef = ReadWriteArgMem;
+    else if (Property->getName() == "Commutative")
+      isCommutative = true;
+    else if (Property->isSubClassOf("NoCapture")) {
+      unsigned ArgNo = Property->getValueAsInt("ArgNo");
+      ArgumentAttributes.push_back(std::make_pair(ArgNo, NoCapture));
+    } else
+      assert(0 && "Unknown property!");
+  }
+}
diff --git a/src/LLVM/utils/TableGen/CodeGenTarget.h b/src/LLVM/utils/TableGen/CodeGenTarget.h
new file mode 100644
index 0000000..6b06b66
--- /dev/null
+++ b/src/LLVM/utils/TableGen/CodeGenTarget.h
@@ -0,0 +1,262 @@
+//===- CodeGenTarget.h - Target Class Wrapper -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines wrappers for the Target class and related global
+// functionality.  This makes it easier to access the data and provides a single
+// place that needs to check it for validity.  All of these classes throw
+// exceptions on error conditions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CODEGEN_TARGET_H
+#define CODEGEN_TARGET_H
+
+#include "CodeGenRegisters.h"
+#include "CodeGenInstruction.h"
+#include "Record.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+
+namespace llvm {
+
+struct CodeGenRegister;
+class CodeGenTarget;
+
+// SelectionDAG node properties.
+//  SDNPMemOperand: indicates that a node touches memory and therefore must
+//                  have an associated memory operand that describes the access.
+enum SDNP {
+  SDNPCommutative, 
+  SDNPAssociative, 
+  SDNPHasChain,
+  SDNPOutFlag,
+  SDNPInFlag,
+  SDNPOptInFlag,
+  SDNPMayLoad,
+  SDNPMayStore,
+  SDNPSideEffect,
+  SDNPMemOperand,
+  SDNPVariadic
+};
+
+/// getValueType - Return the MVT::SimpleValueType that the specified TableGen
+/// record corresponds to.
+MVT::SimpleValueType getValueType(Record *Rec);
+
+std::string getName(MVT::SimpleValueType T);
+std::string getEnumName(MVT::SimpleValueType T);
+
+/// getQualifiedName - Return the name of the specified record, with a
+/// namespace qualifier if the record contains one.
+std::string getQualifiedName(const Record *R);
+  
+/// CodeGenTarget - This class corresponds to the Target class in the .td files.
+///
+class CodeGenTarget {
+  Record *TargetRec;
+
+  mutable DenseMap<const Record*, CodeGenInstruction*> Instructions;
+  mutable std::vector<CodeGenRegister> Registers;
+  mutable std::vector<Record*> SubRegIndices;
+  mutable std::vector<CodeGenRegisterClass> RegisterClasses;
+  mutable std::vector<MVT::SimpleValueType> LegalValueTypes;
+  void ReadRegisters() const;
+  void ReadSubRegIndices() const;
+  void ReadRegisterClasses() const;
+  void ReadInstructions() const;
+  void ReadLegalValueTypes() const;
+  
+  mutable std::vector<const CodeGenInstruction*> InstrsByEnum;
+public:
+  CodeGenTarget();
+
+  Record *getTargetRecord() const { return TargetRec; }
+  const std::string &getName() const;
+
+  /// getInstNamespace - Return the target-specific instruction namespace.
+  ///
+  std::string getInstNamespace() const;
+
+  /// getInstructionSet - Return the InstructionSet object.
+  ///
+  Record *getInstructionSet() const;
+
+  /// getAsmParser - Return the AssemblyParser definition for this target.
+  ///
+  Record *getAsmParser() const;
+
+  /// getAsmWriter - Return the AssemblyWriter definition for this target.
+  ///
+  Record *getAsmWriter() const;
+
+  const std::vector<CodeGenRegister> &getRegisters() const {
+    if (Registers.empty()) ReadRegisters();
+    return Registers;
+  }
+
+  const std::vector<Record*> &getSubRegIndices() const {
+    if (SubRegIndices.empty()) ReadSubRegIndices();
+    return SubRegIndices;
+  }
+
+  // Map a SubRegIndex Record to its number.
+  unsigned getSubRegIndexNo(Record *idx) const {
+    if (SubRegIndices.empty()) ReadSubRegIndices();
+    std::vector<Record*>::const_iterator i =
+      std::find(SubRegIndices.begin(), SubRegIndices.end(), idx);
+    assert(i != SubRegIndices.end() && "Not a SubRegIndex");
+    return (i - SubRegIndices.begin()) + 1;
+  }
+
+  const std::vector<CodeGenRegisterClass> &getRegisterClasses() const {
+    if (RegisterClasses.empty()) ReadRegisterClasses();
+    return RegisterClasses;
+  }
+
+  const CodeGenRegisterClass &getRegisterClass(Record *R) const {
+    const std::vector<CodeGenRegisterClass> &RC = getRegisterClasses();
+    for (unsigned i = 0, e = RC.size(); i != e; ++i)
+      if (RC[i].TheDef == R)
+        return RC[i];
+    assert(0 && "Didn't find the register class");
+    abort();
+  }
+  
+  /// getRegisterClassForRegister - Find the register class that contains the
+  /// specified physical register.  If the register is not in a register
+  /// class, return null. If the register is in multiple classes, and the
+  /// classes have a superset-subset relationship and the same set of
+  /// types, return the superclass.  Otherwise return null.
+  const CodeGenRegisterClass *getRegisterClassForRegister(Record *R) const {
+    const std::vector<CodeGenRegisterClass> &RCs = getRegisterClasses();
+    const CodeGenRegisterClass *FoundRC = 0;
+    for (unsigned i = 0, e = RCs.size(); i != e; ++i) {
+      const CodeGenRegisterClass &RC = RegisterClasses[i];
+      for (unsigned ei = 0, ee = RC.Elements.size(); ei != ee; ++ei) {
+        if (R != RC.Elements[ei])
+          continue;
+
+        // If a register's classes have different types, return null.
+        if (FoundRC && RC.getValueTypes() != FoundRC->getValueTypes())
+          return 0;
+
+        // If this is the first class that contains the register,
+        // make a note of it and go on to the next class.
+        if (!FoundRC) {
+          FoundRC = &RC;
+          break;
+        }
+
+        std::vector<Record *> Elements(RC.Elements);
+        std::vector<Record *> FoundElements(FoundRC->Elements);
+        std::sort(Elements.begin(), Elements.end());
+        std::sort(FoundElements.begin(), FoundElements.end());
+
+        // Check to see if the previously found class that contains
+        // the register is a subclass of the current class. If so,
+        // prefer the superclass.
+        if (std::includes(Elements.begin(), Elements.end(),
+                          FoundElements.begin(), FoundElements.end())) {
+          FoundRC = &RC;
+          break;
+        }
+
+        // Check to see if the previously found class that contains
+        // the register is a superclass of the current class. If so,
+        // prefer the superclass.
+        if (std::includes(FoundElements.begin(), FoundElements.end(),
+                          Elements.begin(), Elements.end()))
+          break;
+
+        // Multiple classes, and neither is a superclass of the other.
+        // Return null.
+        return 0;
+      }
+    }
+    return FoundRC;
+  }
+
+  /// getRegisterVTs - Find the union of all possible SimpleValueTypes for the
+  /// specified physical register.
+  std::vector<MVT::SimpleValueType> getRegisterVTs(Record *R) const;
+  
+  const std::vector<MVT::SimpleValueType> &getLegalValueTypes() const {
+    if (LegalValueTypes.empty()) ReadLegalValueTypes();
+    return LegalValueTypes;
+  }
+  
+  /// isLegalValueType - Return true if the specified value type is natively
+  /// supported by the target (i.e. there are registers that directly hold it).
+  bool isLegalValueType(MVT::SimpleValueType VT) const {
+    const std::vector<MVT::SimpleValueType> &LegalVTs = getLegalValueTypes();
+    for (unsigned i = 0, e = LegalVTs.size(); i != e; ++i)
+      if (LegalVTs[i] == VT) return true;
+    return false;    
+  }
+
+private:
+  DenseMap<const Record*, CodeGenInstruction*> &getInstructions() const {
+    if (Instructions.empty()) ReadInstructions();
+    return Instructions;
+  }
+public:
+  
+  CodeGenInstruction &getInstruction(const Record *InstRec) const {
+    if (Instructions.empty()) ReadInstructions();
+    DenseMap<const Record*, CodeGenInstruction*>::iterator I =
+      Instructions.find(InstRec);
+    assert(I != Instructions.end() && "Not an instruction");
+    return *I->second;
+  }
+
+  /// getInstructionsByEnumValue - Return all of the instructions defined by the
+  /// target, ordered by their enum value.
+  const std::vector<const CodeGenInstruction*> &
+  getInstructionsByEnumValue() const {
+    if (InstrsByEnum.empty()) ComputeInstrsByEnum();
+    return InstrsByEnum;
+  }
+
+  typedef std::vector<const CodeGenInstruction*>::const_iterator inst_iterator;
+  inst_iterator inst_begin() const{return getInstructionsByEnumValue().begin();}
+  inst_iterator inst_end() const { return getInstructionsByEnumValue().end(); }
+  
+  
+  /// isLittleEndianEncoding - are instruction bit patterns defined as  [0..n]?
+  ///
+  bool isLittleEndianEncoding() const;
+  
+private:
+  void ComputeInstrsByEnum() const;
+};
+
+/// ComplexPattern - ComplexPattern info, corresponding to the ComplexPattern
+/// tablegen class in TargetSelectionDAG.td
+class ComplexPattern {
+  MVT::SimpleValueType Ty;
+  unsigned NumOperands;
+  std::string SelectFunc;
+  std::vector<Record*> RootNodes;
+  unsigned Properties; // Node properties
+public:
+  ComplexPattern() : NumOperands(0) {}
+  ComplexPattern(Record *R);
+
+  MVT::SimpleValueType getValueType() const { return Ty; }
+  unsigned getNumOperands() const { return NumOperands; }
+  const std::string &getSelectFunc() const { return SelectFunc; }
+  const std::vector<Record*> &getRootNodes() const {
+    return RootNodes;
+  }
+  bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/utils/TableGen/DAGISelEmitter.cpp b/src/LLVM/utils/TableGen/DAGISelEmitter.cpp
new file mode 100644
index 0000000..04c7710
--- /dev/null
+++ b/src/LLVM/utils/TableGen/DAGISelEmitter.cpp
@@ -0,0 +1,203 @@
+//===- DAGISelEmitter.cpp - Generate an instruction selector --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend emits a DAG instruction selector.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DAGISelEmitter.h"
+#include "DAGISelMatcher.h"
+#include "Record.h"
+#include "llvm/Support/Debug.h"
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// DAGISelEmitter Helper methods
+//
+
+/// getResultPatternCost - Compute the number of instructions for this pattern.
+/// This is a temporary hack.  We should really include the instruction
+/// latencies in this calculation.
+static unsigned getResultPatternCost(TreePatternNode *P,
+                                     CodeGenDAGPatterns &CGP) {
+  if (P->isLeaf()) return 0;
+  
+  unsigned Cost = 0;
+  Record *Op = P->getOperator();
+  if (Op->isSubClassOf("Instruction")) {
+    Cost++;
+    CodeGenInstruction &II = CGP.getTargetInfo().getInstruction(Op);
+    if (II.usesCustomInserter)
+      Cost += 10;
+  }
+  for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i)
+    Cost += getResultPatternCost(P->getChild(i), CGP);
+  return Cost;
+}
+
+/// getResultPatternCodeSize - Compute the code size of instructions for this
+/// pattern.
+static unsigned getResultPatternSize(TreePatternNode *P, 
+                                     CodeGenDAGPatterns &CGP) {
+  if (P->isLeaf()) return 0;
+
+  unsigned Cost = 0;
+  Record *Op = P->getOperator();
+  if (Op->isSubClassOf("Instruction")) {
+    Cost += Op->getValueAsInt("CodeSize");
+  }
+  for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i)
+    Cost += getResultPatternSize(P->getChild(i), CGP);
+  return Cost;
+}
+
+//===----------------------------------------------------------------------===//
+// Predicate emitter implementation.
+//
+
+void DAGISelEmitter::EmitPredicateFunctions(raw_ostream &OS) {
+  OS << "\n// Predicate functions.\n";
+
+  // Walk the pattern fragments, adding them to a map, which sorts them by
+  // name.
+  typedef std::map<std::string, std::pair<Record*, TreePattern*> > PFsByNameTy;
+  PFsByNameTy PFsByName;
+
+  for (CodeGenDAGPatterns::pf_iterator I = CGP.pf_begin(), E = CGP.pf_end();
+       I != E; ++I)
+    PFsByName.insert(std::make_pair(I->first->getName(), *I));
+
+  
+  for (PFsByNameTy::iterator I = PFsByName.begin(), E = PFsByName.end();
+       I != E; ++I) {
+    Record *PatFragRecord = I->second.first;// Record that derives from PatFrag.
+    TreePattern *P = I->second.second;
+    
+    // If there is a code init for this fragment, emit the predicate code.
+    std::string Code = PatFragRecord->getValueAsCode("Predicate");
+    if (Code.empty()) continue;
+    
+    if (P->getOnlyTree()->isLeaf())
+      OS << "inline bool Predicate_" << PatFragRecord->getName()
+      << "(SDNode *N) const {\n";
+    else {
+      std::string ClassName =
+        CGP.getSDNodeInfo(P->getOnlyTree()->getOperator()).getSDClassName();
+      const char *C2 = ClassName == "SDNode" ? "N" : "inN";
+      
+      OS << "inline bool Predicate_" << PatFragRecord->getName()
+         << "(SDNode *" << C2 << ") const {\n";
+      if (ClassName != "SDNode")
+        OS << "  " << ClassName << " *N = cast<" << ClassName << ">(inN);\n";
+    }
+    OS << Code << "\n}\n";
+  }
+  
+  OS << "\n\n";
+}
+
+namespace {
+// PatternSortingPredicate - return true if we prefer to match LHS before RHS.
+// In particular, we want to match maximal patterns first and lowest cost within
+// a particular complexity first.
+struct PatternSortingPredicate {
+  PatternSortingPredicate(CodeGenDAGPatterns &cgp) : CGP(cgp) {}
+  CodeGenDAGPatterns &CGP;
+  
+  bool operator()(const PatternToMatch *LHS, const PatternToMatch *RHS) {
+    const TreePatternNode *LHSSrc = LHS->getSrcPattern();
+    const TreePatternNode *RHSSrc = RHS->getSrcPattern();
+    
+    if (LHSSrc->getNumTypes() != 0 && RHSSrc->getNumTypes() != 0 &&
+        LHSSrc->getType(0) != RHSSrc->getType(0)) {
+      MVT::SimpleValueType V1 = LHSSrc->getType(0), V2 = RHSSrc->getType(0);
+      if (MVT(V1).isVector() != MVT(V2).isVector())
+        return MVT(V2).isVector();
+      
+      if (MVT(V1).isFloatingPoint() != MVT(V2).isFloatingPoint())
+        return MVT(V2).isFloatingPoint();
+    }
+    
+    // Otherwise, if the patterns might both match, sort based on complexity,
+    // which means that we prefer to match patterns that cover more nodes in the
+    // input over nodes that cover fewer.
+    unsigned LHSSize = LHS->getPatternComplexity(CGP);
+    unsigned RHSSize = RHS->getPatternComplexity(CGP);
+    if (LHSSize > RHSSize) return true;   // LHS -> bigger -> less cost
+    if (LHSSize < RHSSize) return false;
+    
+    // If the patterns have equal complexity, compare generated instruction cost
+    unsigned LHSCost = getResultPatternCost(LHS->getDstPattern(), CGP);
+    unsigned RHSCost = getResultPatternCost(RHS->getDstPattern(), CGP);
+    if (LHSCost < RHSCost) return true;
+    if (LHSCost > RHSCost) return false;
+    
+    unsigned LHSPatSize = getResultPatternSize(LHS->getDstPattern(), CGP);
+    unsigned RHSPatSize = getResultPatternSize(RHS->getDstPattern(), CGP);
+    if (LHSPatSize < RHSPatSize) return true;
+    if (LHSPatSize > RHSPatSize) return false;
+    
+    // Sort based on the UID of the pattern, giving us a deterministic ordering
+    // if all other sorting conditions fail.
+    assert(LHS == RHS || LHS->ID != RHS->ID);
+    return LHS->ID < RHS->ID;
+  }
+};
+}
+
+
+void DAGISelEmitter::run(raw_ostream &OS) {
+  EmitSourceFileHeader("DAG Instruction Selector for the " +
+                       CGP.getTargetInfo().getName() + " target", OS);
+  
+  OS << "// *** NOTE: This file is #included into the middle of the target\n"
+     << "// *** instruction selector class.  These functions are really "
+     << "methods.\n\n";
+
+  DEBUG(errs() << "\n\nALL PATTERNS TO MATCH:\n\n";
+        for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(),
+             E = CGP.ptm_end(); I != E; ++I) {
+          errs() << "PATTERN: ";   I->getSrcPattern()->dump();
+          errs() << "\nRESULT:  "; I->getDstPattern()->dump();
+          errs() << "\n";
+        });
+
+  // FIXME: These are being used by hand written code, gross.
+  EmitPredicateFunctions(OS);
+
+  // Add all the patterns to a temporary list so we can sort them.
+  std::vector<const PatternToMatch*> Patterns;
+  for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(), E = CGP.ptm_end();
+       I != E; ++I)
+    Patterns.push_back(&*I);
+
+  // We want to process the matches in order of minimal cost.  Sort the patterns
+  // so the least cost one is at the start.
+  std::sort(Patterns.begin(), Patterns.end(), PatternSortingPredicate(CGP));
+  
+  
+  // Convert each variant of each pattern into a Matcher.
+  std::vector<Matcher*> PatternMatchers;
+  for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
+    for (unsigned Variant = 0; ; ++Variant) {
+      if (Matcher *M = ConvertPatternToMatcher(*Patterns[i], Variant, CGP))
+        PatternMatchers.push_back(M);
+      else
+        break;
+    }
+  }
+          
+  Matcher *TheMatcher = new ScopeMatcher(&PatternMatchers[0],
+                                         PatternMatchers.size());
+
+  TheMatcher = OptimizeMatcher(TheMatcher, CGP);
+  //Matcher->dump();
+  EmitMatcherTable(TheMatcher, CGP, OS);
+  delete TheMatcher;
+}
diff --git a/src/LLVM/utils/TableGen/DAGISelEmitter.h b/src/LLVM/utils/TableGen/DAGISelEmitter.h
new file mode 100644
index 0000000..5ffdde8
--- /dev/null
+++ b/src/LLVM/utils/TableGen/DAGISelEmitter.h
@@ -0,0 +1,40 @@
+//===- DAGISelEmitter.h - Generate an instruction selector ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend emits a DAG instruction selector.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef DAGISEL_EMITTER_H
+#define DAGISEL_EMITTER_H
+
+#include "TableGenBackend.h"
+#include "CodeGenDAGPatterns.h"
+#include <set>
+
+namespace llvm {
+
+/// DAGISelEmitter - The top-level class which coordinates construction
+/// and emission of the instruction selector.
+///
+class DAGISelEmitter : public TableGenBackend {
+  RecordKeeper &Records;
+  CodeGenDAGPatterns CGP;
+public:
+  explicit DAGISelEmitter(RecordKeeper &R) : Records(R), CGP(R) {}
+
+  // run - Output the isel, returning true on failure.
+  void run(raw_ostream &OS);
+private:
+  void EmitPredicateFunctions(raw_ostream &OS);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/utils/TableGen/DAGISelMatcher.cpp b/src/LLVM/utils/TableGen/DAGISelMatcher.cpp
new file mode 100644
index 0000000..9f12a68
--- /dev/null
+++ b/src/LLVM/utils/TableGen/DAGISelMatcher.cpp
@@ -0,0 +1,401 @@
+//===- DAGISelMatcher.cpp - Representation of DAG pattern matcher ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DAGISelMatcher.h"
+#include "CodeGenDAGPatterns.h"
+#include "CodeGenTarget.h"
+#include "Record.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/StringExtras.h"
+using namespace llvm;
+
+void Matcher::dump() const {
+  print(errs(), 0);
+}
+
+void Matcher::print(raw_ostream &OS, unsigned indent) const {
+  printImpl(OS, indent);
+  if (Next)
+    return Next->print(OS, indent);
+}
+
+void Matcher::printOne(raw_ostream &OS) const {
+  printImpl(OS, 0);
+}
+
+/// unlinkNode - Unlink the specified node from this chain.  If Other == this,
+/// we unlink the next pointer and return it.  Otherwise we unlink Other from
+/// the list and return this.
+Matcher *Matcher::unlinkNode(Matcher *Other) {
+  if (this == Other)
+    return takeNext();
+ 
+  // Scan until we find the predecessor of Other.
+  Matcher *Cur = this;
+  for (; Cur && Cur->getNext() != Other; Cur = Cur->getNext())
+    /*empty*/;
+
+  if (Cur == 0) return 0;
+  Cur->takeNext();
+  Cur->setNext(Other->takeNext());
+  return this;
+}
+
+/// canMoveBefore - Return true if this matcher is the same as Other, or if
+/// we can move this matcher past all of the nodes in-between Other and this
+/// node.  Other must be equal to or before this.
+bool Matcher::canMoveBefore(const Matcher *Other) const {
+  for (;; Other = Other->getNext()) {
+    assert(Other && "Other didn't come before 'this'?");
+    if (this == Other) return true;
+
+    // We have to be able to move this node across the Other node.
+    if (!canMoveBeforeNode(Other))
+      return false;
+  }
+}
+
+/// canMoveBefore - Return true if it is safe to move the current matcher
+/// across the specified one.
+bool Matcher::canMoveBeforeNode(const Matcher *Other) const {
+  // We can move simple predicates before record nodes.
+  if (isSimplePredicateNode())
+    return Other->isSimplePredicateOrRecordNode();
+  
+  // We can move record nodes across simple predicates.
+  if (isSimplePredicateOrRecordNode())
+    return isSimplePredicateNode();
+  
+  // We can't move record nodes across each other etc.
+  return false;
+}
+
+
+ScopeMatcher::~ScopeMatcher() {
+  for (unsigned i = 0, e = Children.size(); i != e; ++i)
+    delete Children[i];
+}
+
+
+// printImpl methods.
+
+void ScopeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "Scope\n";
+  for (unsigned i = 0, e = getNumChildren(); i != e; ++i) {
+    if (getChild(i) == 0)
+      OS.indent(indent+1) << "NULL POINTER\n";
+    else
+      getChild(i)->print(OS, indent+2);
+  }
+}
+
+void RecordMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "Record\n";
+}
+
+void RecordChildMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "RecordChild: " << ChildNo << '\n';
+}
+
+void RecordMemRefMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "RecordMemRef\n";
+}
+
+void CaptureFlagInputMatcher::printImpl(raw_ostream &OS, unsigned indent) const{
+  OS.indent(indent) << "CaptureFlagInput\n";
+}
+
+void MoveChildMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "MoveChild " << ChildNo << '\n';
+}
+
+void MoveParentMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "MoveParent\n";
+}
+
+void CheckSameMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "CheckSame " << MatchNumber << '\n';
+}
+
+void CheckPatternPredicateMatcher::
+printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "CheckPatternPredicate " << Predicate << '\n';
+}
+
+void CheckPredicateMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "CheckPredicate " << PredName << '\n';
+}
+
+void CheckOpcodeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "CheckOpcode " << Opcode.getEnumName() << '\n';
+}
+
+void SwitchOpcodeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "SwitchOpcode: {\n";
+  for (unsigned i = 0, e = Cases.size(); i != e; ++i) {
+    OS.indent(indent) << "case " << Cases[i].first->getEnumName() << ":\n";
+    Cases[i].second->print(OS, indent+2);
+  }
+  OS.indent(indent) << "}\n";
+}
+
+
+void CheckTypeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "CheckType " << getEnumName(Type) << ", ResNo="
+    << ResNo << '\n';
+}
+
+void SwitchTypeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "SwitchType: {\n";
+  for (unsigned i = 0, e = Cases.size(); i != e; ++i) {
+    OS.indent(indent) << "case " << getEnumName(Cases[i].first) << ":\n";
+    Cases[i].second->print(OS, indent+2);
+  }
+  OS.indent(indent) << "}\n";
+}
+
+void CheckChildTypeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "CheckChildType " << ChildNo << " "
+    << getEnumName(Type) << '\n';
+}
+
+
+void CheckIntegerMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "CheckInteger " << Value << '\n';
+}
+
+void CheckCondCodeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "CheckCondCode ISD::" << CondCodeName << '\n';
+}
+
+void CheckValueTypeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "CheckValueType MVT::" << TypeName << '\n';
+}
+
+void CheckComplexPatMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "CheckComplexPat " << Pattern.getSelectFunc() << '\n';
+}
+
+void CheckAndImmMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "CheckAndImm " << Value << '\n';
+}
+
+void CheckOrImmMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "CheckOrImm " << Value << '\n';
+}
+
+void CheckFoldableChainNodeMatcher::printImpl(raw_ostream &OS,
+                                              unsigned indent) const {
+  OS.indent(indent) << "CheckFoldableChainNode\n";
+}
+
+void EmitIntegerMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "EmitInteger " << Val << " VT=" << VT << '\n';
+}
+
+void EmitStringIntegerMatcher::
+printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "EmitStringInteger " << Val << " VT=" << VT << '\n';
+}
+
+void EmitRegisterMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "EmitRegister ";
+  if (Reg)
+    OS << Reg->getName();
+  else
+    OS << "zero_reg";
+  OS << " VT=" << VT << '\n';
+}
+
+void EmitConvertToTargetMatcher::
+printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "EmitConvertToTarget " << Slot << '\n';
+}
+
+void EmitMergeInputChainsMatcher::
+printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "EmitMergeInputChains <todo: args>\n";
+}
+
+void EmitCopyToRegMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "EmitCopyToReg <todo: args>\n";
+}
+
+void EmitNodeXFormMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "EmitNodeXForm " << NodeXForm->getName()
+     << " Slot=" << Slot << '\n';
+}
+
+
+void EmitNodeMatcherCommon::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent);
+  OS << (isa<MorphNodeToMatcher>(this) ? "MorphNodeTo: " : "EmitNode: ")
+     << OpcodeName << ": <todo flags> ";
+
+  for (unsigned i = 0, e = VTs.size(); i != e; ++i)
+    OS << ' ' << getEnumName(VTs[i]);
+  OS << '(';
+  for (unsigned i = 0, e = Operands.size(); i != e; ++i)
+    OS << Operands[i] << ' ';
+  OS << ")\n";
+}
+
+void MarkFlagResultsMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "MarkFlagResults <todo: args>\n";
+}
+
+void CompleteMatchMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "CompleteMatch <todo args>\n";
+  OS.indent(indent) << "Src = " << *Pattern.getSrcPattern() << "\n";
+  OS.indent(indent) << "Dst = " << *Pattern.getDstPattern() << "\n";
+}
+
+// getHashImpl Implementation.
+
+unsigned CheckPatternPredicateMatcher::getHashImpl() const {
+  return HashString(Predicate);
+}
+
+unsigned CheckPredicateMatcher::getHashImpl() const {
+  return HashString(PredName);
+}
+
+unsigned CheckOpcodeMatcher::getHashImpl() const {
+  return HashString(Opcode.getEnumName());
+}
+
+unsigned CheckCondCodeMatcher::getHashImpl() const {
+  return HashString(CondCodeName);
+}
+
+unsigned CheckValueTypeMatcher::getHashImpl() const {
+  return HashString(TypeName);
+}
+
+unsigned EmitStringIntegerMatcher::getHashImpl() const {
+  return HashString(Val) ^ VT;
+}
+
+template<typename It>
+static unsigned HashUnsigneds(It I, It E) {
+  unsigned Result = 0;
+  for (; I != E; ++I)
+    Result = (Result<<3) ^ *I;
+  return Result;
+}
+
+unsigned EmitMergeInputChainsMatcher::getHashImpl() const {
+  return HashUnsigneds(ChainNodes.begin(), ChainNodes.end());
+}
+
+bool CheckOpcodeMatcher::isEqualImpl(const Matcher *M) const {
+  // Note: pointer equality isn't enough here, we have to check the enum names
+  // to ensure that the nodes are for the same opcode. 
+  return cast<CheckOpcodeMatcher>(M)->Opcode.getEnumName() ==
+          Opcode.getEnumName();
+}
+
+
+bool EmitNodeMatcherCommon::isEqualImpl(const Matcher *m) const {
+  const EmitNodeMatcherCommon *M = cast<EmitNodeMatcherCommon>(m);
+  return M->OpcodeName == OpcodeName && M->VTs == VTs &&
+         M->Operands == Operands && M->HasChain == HasChain &&
+         M->HasInFlag == HasInFlag && M->HasOutFlag == HasOutFlag &&
+         M->HasMemRefs == HasMemRefs &&
+         M->NumFixedArityOperands == NumFixedArityOperands;
+}
+
+unsigned EmitNodeMatcherCommon::getHashImpl() const {
+  return (HashString(OpcodeName) << 4) | Operands.size();
+}
+
+
+unsigned MarkFlagResultsMatcher::getHashImpl() const {
+  return HashUnsigneds(FlagResultNodes.begin(), FlagResultNodes.end());
+}
+
+unsigned CompleteMatchMatcher::getHashImpl() const {
+  return HashUnsigneds(Results.begin(), Results.end()) ^ 
+          ((unsigned)(intptr_t)&Pattern << 8);
+}
+
+// isContradictoryImpl Implementations.
+
+static bool TypesAreContradictory(MVT::SimpleValueType T1,
+                                  MVT::SimpleValueType T2) {
+  // If the two types are the same, then they are the same, so they don't
+  // contradict.
+  if (T1 == T2) return false;
+  
+  // If either type is about iPtr, then they don't conflict unless the other
+  // one is not a scalar integer type.
+  if (T1 == MVT::iPTR)
+    return !MVT(T2).isInteger() || MVT(T2).isVector();
+  
+  if (T2 == MVT::iPTR)
+    return !MVT(T1).isInteger() || MVT(T1).isVector();
+  
+  // Otherwise, they are two different non-iPTR types, they conflict.
+  return true;
+}
+
+bool CheckOpcodeMatcher::isContradictoryImpl(const Matcher *M) const {
+  if (const CheckOpcodeMatcher *COM = dyn_cast<CheckOpcodeMatcher>(M)) {
+    // One node can't have two different opcodes!
+    // Note: pointer equality isn't enough here, we have to check the enum names
+    // to ensure that the nodes are for the same opcode. 
+    return COM->getOpcode().getEnumName() != getOpcode().getEnumName();
+  }
+  
+  // If the node has a known type, and if the type we're checking for is
+  // different, then we know they contradict.  For example, a check for
+  // ISD::STORE will never be true at the same time a check for Type i32 is.
+  if (const CheckTypeMatcher *CT = dyn_cast<CheckTypeMatcher>(M)) {
+    // If checking for a result the opcode doesn't have, it can't match.
+    if (CT->getResNo() >= getOpcode().getNumResults())
+      return true;
+    
+    MVT::SimpleValueType NodeType = getOpcode().getKnownType(CT->getResNo());
+    if (NodeType != MVT::Other)
+      return TypesAreContradictory(NodeType, CT->getType());
+  }
+  
+  return false;
+}
+
+bool CheckTypeMatcher::isContradictoryImpl(const Matcher *M) const {
+  if (const CheckTypeMatcher *CT = dyn_cast<CheckTypeMatcher>(M))
+    return TypesAreContradictory(getType(), CT->getType());
+  return false;
+}
+
+bool CheckChildTypeMatcher::isContradictoryImpl(const Matcher *M) const {
+  if (const CheckChildTypeMatcher *CC = dyn_cast<CheckChildTypeMatcher>(M)) {
+    // If the two checks are about different nodes, we don't know if they
+    // conflict!
+    if (CC->getChildNo() != getChildNo())
+      return false;
+    
+    return TypesAreContradictory(getType(), CC->getType());
+  }
+  return false;
+}
+  
+bool CheckIntegerMatcher::isContradictoryImpl(const Matcher *M) const {
+  if (const CheckIntegerMatcher *CIM = dyn_cast<CheckIntegerMatcher>(M))
+    return CIM->getValue() != getValue();
+  return false;
+}
+
+bool CheckValueTypeMatcher::isContradictoryImpl(const Matcher *M) const {
+  if (const CheckValueTypeMatcher *CVT = dyn_cast<CheckValueTypeMatcher>(M))
+    return CVT->getTypeName() != getTypeName();
+  return false;
+}
+
diff --git a/src/LLVM/utils/TableGen/DAGISelMatcher.h b/src/LLVM/utils/TableGen/DAGISelMatcher.h
new file mode 100644
index 0000000..d9b25d5
--- /dev/null
+++ b/src/LLVM/utils/TableGen/DAGISelMatcher.h
@@ -0,0 +1,1114 @@
+//===- DAGISelMatcher.h - Representation of DAG pattern matcher -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TBLGEN_DAGISELMATCHER_H
+#define TBLGEN_DAGISELMATCHER_H
+
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Casting.h"
+
+namespace llvm {
+  class CodeGenDAGPatterns;
+  class Matcher;
+  class PatternToMatch;
+  class raw_ostream;
+  class ComplexPattern;
+  class Record;
+  class SDNodeInfo;
+
+Matcher *ConvertPatternToMatcher(const PatternToMatch &Pattern,unsigned Variant,
+                                 const CodeGenDAGPatterns &CGP);
+Matcher *OptimizeMatcher(Matcher *Matcher, const CodeGenDAGPatterns &CGP);
+void EmitMatcherTable(const Matcher *Matcher, const CodeGenDAGPatterns &CGP,
+                      raw_ostream &OS);
+
+  
+/// Matcher - Base class for all the the DAG ISel Matcher representation
+/// nodes.
+class Matcher {
+  // The next matcher node that is executed after this one.  Null if this is the
+  // last stage of a match.
+  OwningPtr<Matcher> Next;
+public:
+  enum KindTy {
+    // Matcher state manipulation.
+    Scope,                // Push a checking scope.
+    RecordNode,           // Record the current node.
+    RecordChild,          // Record a child of the current node.
+    RecordMemRef,         // Record the memref in the current node.
+    CaptureFlagInput,     // If the current node has an input flag, save it.
+    MoveChild,            // Move current node to specified child.
+    MoveParent,           // Move current node to parent.
+    
+    // Predicate checking.
+    CheckSame,            // Fail if not same as prev match.
+    CheckPatternPredicate,
+    CheckPredicate,       // Fail if node predicate fails.
+    CheckOpcode,          // Fail if not opcode.
+    SwitchOpcode,         // Dispatch based on opcode.
+    CheckType,            // Fail if not correct type.
+    SwitchType,           // Dispatch based on type.
+    CheckChildType,       // Fail if child has wrong type.
+    CheckInteger,         // Fail if wrong val.
+    CheckCondCode,        // Fail if not condcode.
+    CheckValueType,
+    CheckComplexPat,
+    CheckAndImm,
+    CheckOrImm,
+    CheckFoldableChainNode,
+    
+    // Node creation/emisssion.
+    EmitInteger,          // Create a TargetConstant
+    EmitStringInteger,    // Create a TargetConstant from a string.
+    EmitRegister,         // Create a register.
+    EmitConvertToTarget,  // Convert a imm/fpimm to target imm/fpimm
+    EmitMergeInputChains, // Merge together a chains for an input.
+    EmitCopyToReg,        // Emit a copytoreg into a physreg.
+    EmitNode,             // Create a DAG node
+    EmitNodeXForm,        // Run a SDNodeXForm
+    MarkFlagResults,      // Indicate which interior nodes have flag results.
+    CompleteMatch,        // Finish a match and update the results.
+    MorphNodeTo           // Build a node, finish a match and update results.
+  };
+  const KindTy Kind;
+
+protected:
+  Matcher(KindTy K) : Kind(K) {}
+public:
+  virtual ~Matcher() {}
+  
+  KindTy getKind() const { return Kind; }
+
+  Matcher *getNext() { return Next.get(); }
+  const Matcher *getNext() const { return Next.get(); }
+  void setNext(Matcher *C) { Next.reset(C); }
+  Matcher *takeNext() { return Next.take(); }
+
+  OwningPtr<Matcher> &getNextPtr() { return Next; }
+  
+  static inline bool classof(const Matcher *) { return true; }
+  
+  bool isEqual(const Matcher *M) const {
+    if (getKind() != M->getKind()) return false;
+    return isEqualImpl(M);
+  }
+  
+  unsigned getHash() const {
+    // Clear the high bit so we don't conflict with tombstones etc.
+    return ((getHashImpl() << 4) ^ getKind()) & (~0U>>1);
+  }
+  
+  /// isSafeToReorderWithPatternPredicate - Return true if it is safe to sink a
+  /// PatternPredicate node past this one.
+  virtual bool isSafeToReorderWithPatternPredicate() const {
+    return false;
+  }
+  
+  /// isSimplePredicateNode - Return true if this is a simple predicate that
+  /// operates on the node or its children without potential side effects or a
+  /// change of the current node.
+  bool isSimplePredicateNode() const {
+    switch (getKind()) {
+    default: return false;
+    case CheckSame:
+    case CheckPatternPredicate:
+    case CheckPredicate:
+    case CheckOpcode:
+    case CheckType:
+    case CheckChildType:
+    case CheckInteger:
+    case CheckCondCode:
+    case CheckValueType:
+    case CheckAndImm:
+    case CheckOrImm:
+    case CheckFoldableChainNode:
+      return true;
+    }
+  }
+  
+  /// isSimplePredicateOrRecordNode - Return true if this is a record node or
+  /// a simple predicate.
+  bool isSimplePredicateOrRecordNode() const {
+    return isSimplePredicateNode() ||
+           getKind() == RecordNode || getKind() == RecordChild;
+  }
+  
+  /// unlinkNode - Unlink the specified node from this chain.  If Other == this,
+  /// we unlink the next pointer and return it.  Otherwise we unlink Other from
+  /// the list and return this.
+  Matcher *unlinkNode(Matcher *Other);
+  
+  /// canMoveBefore - Return true if this matcher is the same as Other, or if
+  /// we can move this matcher past all of the nodes in-between Other and this
+  /// node.  Other must be equal to or before this.
+  bool canMoveBefore(const Matcher *Other) const;
+  
+  /// canMoveBefore - Return true if it is safe to move the current matcher
+  /// across the specified one.
+  bool canMoveBeforeNode(const Matcher *Other) const;
+  
+  /// isContradictory - Return true of these two matchers could never match on
+  /// the same node.
+  bool isContradictory(const Matcher *Other) const {
+    // Since this predicate is reflexive, we canonicalize the ordering so that
+    // we always match a node against nodes with kinds that are greater or equal
+    // to them.  For example, we'll pass in a CheckType node as an argument to
+    // the CheckOpcode method, not the other way around.
+    if (getKind() < Other->getKind())
+      return isContradictoryImpl(Other);
+    return Other->isContradictoryImpl(this);
+  }
+  
+  void print(raw_ostream &OS, unsigned indent = 0) const;
+  void printOne(raw_ostream &OS) const;
+  void dump() const;
+protected:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const = 0;
+  virtual bool isEqualImpl(const Matcher *M) const = 0;
+  virtual unsigned getHashImpl() const = 0;
+  virtual bool isContradictoryImpl(const Matcher *M) const { return false; }
+};
+  
+/// ScopeMatcher - This attempts to match each of its children to find the first
+/// one that successfully matches.  If one child fails, it tries the next child.
+/// If none of the children match then this check fails.  It never has a 'next'.
+class ScopeMatcher : public Matcher {
+  SmallVector<Matcher*, 4> Children;
+public:
+  ScopeMatcher(Matcher *const *children, unsigned numchildren)
+    : Matcher(Scope), Children(children, children+numchildren) {
+  }
+  virtual ~ScopeMatcher();
+  
+  unsigned getNumChildren() const { return Children.size(); }
+  
+  Matcher *getChild(unsigned i) { return Children[i]; }
+  const Matcher *getChild(unsigned i) const { return Children[i]; }
+  
+  void resetChild(unsigned i, Matcher *N) {
+    delete Children[i];
+    Children[i] = N;
+  }
+
+  Matcher *takeChild(unsigned i) {
+    Matcher *Res = Children[i];
+    Children[i] = 0;
+    return Res;
+  }
+  
+  void setNumChildren(unsigned NC) {
+    if (NC < Children.size()) {
+      // delete any children we're about to lose pointers to.
+      for (unsigned i = NC, e = Children.size(); i != e; ++i)
+        delete Children[i];
+    }
+    Children.resize(NC);
+  }
+
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == Scope;
+  }
+  
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const { return false; }
+  virtual unsigned getHashImpl() const { return 12312; }
+};
+
+/// RecordMatcher - Save the current node in the operand list.
+class RecordMatcher : public Matcher {
+  /// WhatFor - This is a string indicating why we're recording this.  This
+  /// should only be used for comment generation not anything semantic.
+  std::string WhatFor;
+  
+  /// ResultNo - The slot number in the RecordedNodes vector that this will be,
+  /// just printed as a comment.
+  unsigned ResultNo;
+public:
+  RecordMatcher(const std::string &whatfor, unsigned resultNo)
+    : Matcher(RecordNode), WhatFor(whatfor), ResultNo(resultNo) {}
+  
+  const std::string &getWhatFor() const { return WhatFor; }
+  unsigned getResultNo() const { return ResultNo; }
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == RecordNode;
+  }
+  
+  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const { return true; }
+  virtual unsigned getHashImpl() const { return 0; }
+};
+  
+/// RecordChildMatcher - Save a numbered child of the current node, or fail
+/// the match if it doesn't exist.  This is logically equivalent to:
+///    MoveChild N + RecordNode + MoveParent.
+class RecordChildMatcher : public Matcher {
+  unsigned ChildNo;
+  
+  /// WhatFor - This is a string indicating why we're recording this.  This
+  /// should only be used for comment generation not anything semantic.
+  std::string WhatFor;
+  
+  /// ResultNo - The slot number in the RecordedNodes vector that this will be,
+  /// just printed as a comment.
+  unsigned ResultNo;
+public:
+  RecordChildMatcher(unsigned childno, const std::string &whatfor,
+                     unsigned resultNo)
+  : Matcher(RecordChild), ChildNo(childno), WhatFor(whatfor),
+    ResultNo(resultNo) {}
+  
+  unsigned getChildNo() const { return ChildNo; }
+  const std::string &getWhatFor() const { return WhatFor; }
+  unsigned getResultNo() const { return ResultNo; }
+
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == RecordChild;
+  }
+  
+  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<RecordChildMatcher>(M)->getChildNo() == getChildNo();
+  }
+  virtual unsigned getHashImpl() const { return getChildNo(); }
+};
+  
+/// RecordMemRefMatcher - Save the current node's memref.
+class RecordMemRefMatcher : public Matcher {
+public:
+  RecordMemRefMatcher() : Matcher(RecordMemRef) {}
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == RecordMemRef;
+  }
+  
+  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const { return true; }
+  virtual unsigned getHashImpl() const { return 0; }
+};
+
+  
+/// CaptureFlagInputMatcher - If the current record has a flag input, record
+/// it so that it is used as an input to the generated code.
+class CaptureFlagInputMatcher : public Matcher {
+public:
+  CaptureFlagInputMatcher() : Matcher(CaptureFlagInput) {}
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == CaptureFlagInput;
+  }
+  
+  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const { return true; }
+  virtual unsigned getHashImpl() const { return 0; }
+};
+  
+/// MoveChildMatcher - This tells the interpreter to move into the
+/// specified child node.
+class MoveChildMatcher : public Matcher {
+  unsigned ChildNo;
+public:
+  MoveChildMatcher(unsigned childNo) : Matcher(MoveChild), ChildNo(childNo) {}
+  
+  unsigned getChildNo() const { return ChildNo; }
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == MoveChild;
+  }
+  
+  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<MoveChildMatcher>(M)->getChildNo() == getChildNo();
+  }
+  virtual unsigned getHashImpl() const { return getChildNo(); }
+};
+  
+/// MoveParentMatcher - This tells the interpreter to move to the parent
+/// of the current node.
+class MoveParentMatcher : public Matcher {
+public:
+  MoveParentMatcher() : Matcher(MoveParent) {}
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == MoveParent;
+  }
+  
+  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const { return true; }
+  virtual unsigned getHashImpl() const { return 0; }
+};
+
+/// CheckSameMatcher - This checks to see if this node is exactly the same
+/// node as the specified match that was recorded with 'Record'.  This is used
+/// when patterns have the same name in them, like '(mul GPR:$in, GPR:$in)'.
+class CheckSameMatcher : public Matcher {
+  unsigned MatchNumber;
+public:
+  CheckSameMatcher(unsigned matchnumber)
+    : Matcher(CheckSame), MatchNumber(matchnumber) {}
+  
+  unsigned getMatchNumber() const { return MatchNumber; }
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == CheckSame;
+  }
+  
+  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<CheckSameMatcher>(M)->getMatchNumber() == getMatchNumber();
+  }
+  virtual unsigned getHashImpl() const { return getMatchNumber(); }
+};
+  
+/// CheckPatternPredicateMatcher - This checks the target-specific predicate
+/// to see if the entire pattern is capable of matching.  This predicate does
+/// not take a node as input.  This is used for subtarget feature checks etc.
+class CheckPatternPredicateMatcher : public Matcher {
+  std::string Predicate;
+public:
+  CheckPatternPredicateMatcher(StringRef predicate)
+    : Matcher(CheckPatternPredicate), Predicate(predicate) {}
+  
+  StringRef getPredicate() const { return Predicate; }
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == CheckPatternPredicate;
+  }
+  
+  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<CheckPatternPredicateMatcher>(M)->getPredicate() == Predicate;
+  }
+  virtual unsigned getHashImpl() const;
+};
+  
+/// CheckPredicateMatcher - This checks the target-specific predicate to
+/// see if the node is acceptable.
+class CheckPredicateMatcher : public Matcher {
+  StringRef PredName;
+public:
+  CheckPredicateMatcher(StringRef predname)
+    : Matcher(CheckPredicate), PredName(predname) {}
+  
+  StringRef getPredicateName() const { return PredName; }
+
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == CheckPredicate;
+  }
+  
+  // TODO: Ok?
+  //virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<CheckPredicateMatcher>(M)->PredName == PredName;
+  }
+  virtual unsigned getHashImpl() const;
+};
+  
+  
+/// CheckOpcodeMatcher - This checks to see if the current node has the
+/// specified opcode, if not it fails to match.
+class CheckOpcodeMatcher : public Matcher {
+  const SDNodeInfo &Opcode;
+public:
+  CheckOpcodeMatcher(const SDNodeInfo &opcode)
+    : Matcher(CheckOpcode), Opcode(opcode) {}
+  
+  const SDNodeInfo &getOpcode() const { return Opcode; }
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == CheckOpcode;
+  }
+  
+  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const;
+  virtual unsigned getHashImpl() const;
+  virtual bool isContradictoryImpl(const Matcher *M) const;
+};
+
+/// SwitchOpcodeMatcher - Switch based on the current node's opcode, dispatching
+/// to one matcher per opcode.  If the opcode doesn't match any of the cases,
+/// then the match fails.  This is semantically equivalent to a Scope node where
+/// every child does a CheckOpcode, but is much faster.
+class SwitchOpcodeMatcher : public Matcher {
+  SmallVector<std::pair<const SDNodeInfo*, Matcher*>, 8> Cases;
+public:
+  SwitchOpcodeMatcher(const std::pair<const SDNodeInfo*, Matcher*> *cases,
+                      unsigned numcases)
+    : Matcher(SwitchOpcode), Cases(cases, cases+numcases) {}
+
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == SwitchOpcode;
+  }
+  
+  unsigned getNumCases() const { return Cases.size(); }
+  
+  const SDNodeInfo &getCaseOpcode(unsigned i) const { return *Cases[i].first; }
+  Matcher *getCaseMatcher(unsigned i) { return Cases[i].second; }
+  const Matcher *getCaseMatcher(unsigned i) const { return Cases[i].second; }
+  
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const { return false; }
+  virtual unsigned getHashImpl() const { return 4123; }
+};
+  
+/// CheckTypeMatcher - This checks to see if the current node has the
+/// specified type at the specified result, if not it fails to match.
+class CheckTypeMatcher : public Matcher {
+  MVT::SimpleValueType Type;
+  unsigned ResNo;
+public:
+  CheckTypeMatcher(MVT::SimpleValueType type, unsigned resno)
+    : Matcher(CheckType), Type(type), ResNo(resno) {}
+  
+  MVT::SimpleValueType getType() const { return Type; }
+  unsigned getResNo() const { return ResNo; }
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == CheckType;
+  }
+  
+  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<CheckTypeMatcher>(M)->Type == Type;
+  }
+  virtual unsigned getHashImpl() const { return Type; }
+  virtual bool isContradictoryImpl(const Matcher *M) const;
+};
+  
+/// SwitchTypeMatcher - Switch based on the current node's type, dispatching
+/// to one matcher per case.  If the type doesn't match any of the cases,
+/// then the match fails.  This is semantically equivalent to a Scope node where
+/// every child does a CheckType, but is much faster.
+class SwitchTypeMatcher : public Matcher {
+  SmallVector<std::pair<MVT::SimpleValueType, Matcher*>, 8> Cases;
+public:
+  SwitchTypeMatcher(const std::pair<MVT::SimpleValueType, Matcher*> *cases,
+                    unsigned numcases)
+  : Matcher(SwitchType), Cases(cases, cases+numcases) {}
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == SwitchType;
+  }
+  
+  unsigned getNumCases() const { return Cases.size(); }
+  
+  MVT::SimpleValueType getCaseType(unsigned i) const { return Cases[i].first; }
+  Matcher *getCaseMatcher(unsigned i) { return Cases[i].second; }
+  const Matcher *getCaseMatcher(unsigned i) const { return Cases[i].second; }
+  
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const { return false; }
+  virtual unsigned getHashImpl() const { return 4123; }
+};
+  
+  
+/// CheckChildTypeMatcher - This checks to see if a child node has the
+/// specified type, if not it fails to match.
+class CheckChildTypeMatcher : public Matcher {
+  unsigned ChildNo;
+  MVT::SimpleValueType Type;
+public:
+  CheckChildTypeMatcher(unsigned childno, MVT::SimpleValueType type)
+    : Matcher(CheckChildType), ChildNo(childno), Type(type) {}
+  
+  unsigned getChildNo() const { return ChildNo; }
+  MVT::SimpleValueType getType() const { return Type; }
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == CheckChildType;
+  }
+  
+  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<CheckChildTypeMatcher>(M)->ChildNo == ChildNo &&
+           cast<CheckChildTypeMatcher>(M)->Type == Type;
+  }
+  virtual unsigned getHashImpl() const { return (Type << 3) | ChildNo; }
+  virtual bool isContradictoryImpl(const Matcher *M) const;
+};
+  
+
+/// CheckIntegerMatcher - This checks to see if the current node is a
+/// ConstantSDNode with the specified integer value, if not it fails to match.
+class CheckIntegerMatcher : public Matcher {
+  int64_t Value;
+public:
+  CheckIntegerMatcher(int64_t value)
+    : Matcher(CheckInteger), Value(value) {}
+  
+  int64_t getValue() const { return Value; }
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == CheckInteger;
+  }
+  
+  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<CheckIntegerMatcher>(M)->Value == Value;
+  }
+  virtual unsigned getHashImpl() const { return Value; }
+  virtual bool isContradictoryImpl(const Matcher *M) const;
+};
+  
+/// CheckCondCodeMatcher - This checks to see if the current node is a
+/// CondCodeSDNode with the specified condition, if not it fails to match.
+class CheckCondCodeMatcher : public Matcher {
+  StringRef CondCodeName;
+public:
+  CheckCondCodeMatcher(StringRef condcodename)
+    : Matcher(CheckCondCode), CondCodeName(condcodename) {}
+  
+  StringRef getCondCodeName() const { return CondCodeName; }
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == CheckCondCode;
+  }
+  
+  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<CheckCondCodeMatcher>(M)->CondCodeName == CondCodeName;
+  }
+  virtual unsigned getHashImpl() const;
+};
+  
+/// CheckValueTypeMatcher - This checks to see if the current node is a
+/// VTSDNode with the specified type, if not it fails to match.
+class CheckValueTypeMatcher : public Matcher {
+  StringRef TypeName;
+public:
+  CheckValueTypeMatcher(StringRef type_name)
+    : Matcher(CheckValueType), TypeName(type_name) {}
+  
+  StringRef getTypeName() const { return TypeName; }
+
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == CheckValueType;
+  }
+  
+  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<CheckValueTypeMatcher>(M)->TypeName == TypeName;
+  }
+  virtual unsigned getHashImpl() const;
+  bool isContradictoryImpl(const Matcher *M) const;
+};
+  
+  
+  
+/// CheckComplexPatMatcher - This node runs the specified ComplexPattern on
+/// the current node.
+class CheckComplexPatMatcher : public Matcher {
+  const ComplexPattern &Pattern;
+  
+  /// MatchNumber - This is the recorded nodes slot that contains the node we want to
+  /// match against.
+  unsigned MatchNumber;
+  
+  /// Name - The name of the node we're matching, for comment emission.
+  std::string Name;
+  
+  /// FirstResult - This is the first slot in the RecordedNodes list that the
+  /// result of the match populates.
+  unsigned FirstResult;
+public:
+  CheckComplexPatMatcher(const ComplexPattern &pattern, unsigned matchnumber,
+                         const std::string &name, unsigned firstresult)
+    : Matcher(CheckComplexPat), Pattern(pattern), MatchNumber(matchnumber),
+      Name(name), FirstResult(firstresult) {}
+  
+  const ComplexPattern &getPattern() const { return Pattern; }
+  unsigned getMatchNumber() const { return MatchNumber; }
+  
+  const std::string getName() const { return Name; }
+  unsigned getFirstResult() const { return FirstResult; }
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == CheckComplexPat;
+  }
+  
+  // Not safe to move a pattern predicate past a complex pattern.
+  virtual bool isSafeToReorderWithPatternPredicate() const { return false; }
+
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return &cast<CheckComplexPatMatcher>(M)->Pattern == &Pattern &&
+           cast<CheckComplexPatMatcher>(M)->MatchNumber == MatchNumber;
+  }
+  virtual unsigned getHashImpl() const {
+    return (unsigned)(intptr_t)&Pattern ^ MatchNumber;
+  }
+};
+  
+/// CheckAndImmMatcher - This checks to see if the current node is an 'and'
+/// with something equivalent to the specified immediate.
+class CheckAndImmMatcher : public Matcher {
+  int64_t Value;
+public:
+  CheckAndImmMatcher(int64_t value)
+    : Matcher(CheckAndImm), Value(value) {}
+  
+  int64_t getValue() const { return Value; }
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == CheckAndImm;
+  }
+  
+  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<CheckAndImmMatcher>(M)->Value == Value;
+  }
+  virtual unsigned getHashImpl() const { return Value; }
+};
+
+/// CheckOrImmMatcher - This checks to see if the current node is an 'and'
+/// with something equivalent to the specified immediate.
+class CheckOrImmMatcher : public Matcher {
+  int64_t Value;
+public:
+  CheckOrImmMatcher(int64_t value)
+    : Matcher(CheckOrImm), Value(value) {}
+  
+  int64_t getValue() const { return Value; }
+
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == CheckOrImm;
+  }
+  
+  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<CheckOrImmMatcher>(M)->Value == Value;
+  }
+  virtual unsigned getHashImpl() const { return Value; }
+};
+
+/// CheckFoldableChainNodeMatcher - This checks to see if the current node
+/// (which defines a chain operand) is safe to fold into a larger pattern.
+class CheckFoldableChainNodeMatcher : public Matcher {
+public:
+  CheckFoldableChainNodeMatcher()
+    : Matcher(CheckFoldableChainNode) {}
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == CheckFoldableChainNode;
+  }
+  
+  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const { return true; }
+  virtual unsigned getHashImpl() const { return 0; }
+};
+
+/// EmitIntegerMatcher - This creates a new TargetConstant.
+class EmitIntegerMatcher : public Matcher {
+  int64_t Val;
+  MVT::SimpleValueType VT;
+public:
+  EmitIntegerMatcher(int64_t val, MVT::SimpleValueType vt)
+    : Matcher(EmitInteger), Val(val), VT(vt) {}
+  
+  int64_t getValue() const { return Val; }
+  MVT::SimpleValueType getVT() const { return VT; }
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == EmitInteger;
+  }
+  
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<EmitIntegerMatcher>(M)->Val == Val &&
+           cast<EmitIntegerMatcher>(M)->VT == VT;
+  }
+  virtual unsigned getHashImpl() const { return (Val << 4) | VT; }
+};
+
+/// EmitStringIntegerMatcher - A target constant whose value is represented
+/// by a string.
+class EmitStringIntegerMatcher : public Matcher {
+  std::string Val;
+  MVT::SimpleValueType VT;
+public:
+  EmitStringIntegerMatcher(const std::string &val, MVT::SimpleValueType vt)
+    : Matcher(EmitStringInteger), Val(val), VT(vt) {}
+  
+  const std::string &getValue() const { return Val; }
+  MVT::SimpleValueType getVT() const { return VT; }
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == EmitStringInteger;
+  }
+  
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<EmitStringIntegerMatcher>(M)->Val == Val &&
+           cast<EmitStringIntegerMatcher>(M)->VT == VT;
+  }
+  virtual unsigned getHashImpl() const;
+};
+  
+/// EmitRegisterMatcher - This creates a new TargetConstant.
+class EmitRegisterMatcher : public Matcher {
+  /// Reg - The def for the register that we're emitting.  If this is null, then
+  /// this is a reference to zero_reg.
+  Record *Reg;
+  MVT::SimpleValueType VT;
+public:
+  EmitRegisterMatcher(Record *reg, MVT::SimpleValueType vt)
+    : Matcher(EmitRegister), Reg(reg), VT(vt) {}
+  
+  Record *getReg() const { return Reg; }
+  MVT::SimpleValueType getVT() const { return VT; }
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == EmitRegister;
+  }
+  
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<EmitRegisterMatcher>(M)->Reg == Reg &&
+           cast<EmitRegisterMatcher>(M)->VT == VT;
+  }
+  virtual unsigned getHashImpl() const {
+    return ((unsigned)(intptr_t)Reg) << 4 | VT;
+  }
+};
+
+/// EmitConvertToTargetMatcher - Emit an operation that reads a specified
+/// recorded node and converts it from being a ISD::Constant to
+/// ISD::TargetConstant, likewise for ConstantFP.
+class EmitConvertToTargetMatcher : public Matcher {
+  unsigned Slot;
+public:
+  EmitConvertToTargetMatcher(unsigned slot)
+    : Matcher(EmitConvertToTarget), Slot(slot) {}
+  
+  unsigned getSlot() const { return Slot; }
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == EmitConvertToTarget;
+  }
+  
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<EmitConvertToTargetMatcher>(M)->Slot == Slot;
+  }
+  virtual unsigned getHashImpl() const { return Slot; }
+};
+  
+/// EmitMergeInputChainsMatcher - Emit a node that merges a list of input
+/// chains together with a token factor.  The list of nodes are the nodes in the
+/// matched pattern that have chain input/outputs.  This node adds all input
+/// chains of these nodes if they are not themselves a node in the pattern.
+class EmitMergeInputChainsMatcher : public Matcher {
+  SmallVector<unsigned, 3> ChainNodes;
+public:
+  EmitMergeInputChainsMatcher(const unsigned *nodes, unsigned NumNodes)
+    : Matcher(EmitMergeInputChains), ChainNodes(nodes, nodes+NumNodes) {}
+  
+  unsigned getNumNodes() const { return ChainNodes.size(); }
+  
+  unsigned getNode(unsigned i) const {
+    assert(i < ChainNodes.size());
+    return ChainNodes[i];
+  }  
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == EmitMergeInputChains;
+  }
+  
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<EmitMergeInputChainsMatcher>(M)->ChainNodes == ChainNodes;
+  }
+  virtual unsigned getHashImpl() const;
+};
+  
+/// EmitCopyToRegMatcher - Emit a CopyToReg node from a value to a physreg,
+/// pushing the chain and flag results.
+///
+class EmitCopyToRegMatcher : public Matcher {
+  unsigned SrcSlot; // Value to copy into the physreg.
+  Record *DestPhysReg;
+public:
+  EmitCopyToRegMatcher(unsigned srcSlot, Record *destPhysReg)
+    : Matcher(EmitCopyToReg), SrcSlot(srcSlot), DestPhysReg(destPhysReg) {}
+  
+  unsigned getSrcSlot() const { return SrcSlot; }
+  Record *getDestPhysReg() const { return DestPhysReg; }
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == EmitCopyToReg;
+  }
+  
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<EmitCopyToRegMatcher>(M)->SrcSlot == SrcSlot &&
+           cast<EmitCopyToRegMatcher>(M)->DestPhysReg == DestPhysReg; 
+  }
+  virtual unsigned getHashImpl() const {
+    return SrcSlot ^ ((unsigned)(intptr_t)DestPhysReg << 4);
+  }
+};
+  
+    
+  
+/// EmitNodeXFormMatcher - Emit an operation that runs an SDNodeXForm on a
+/// recorded node and records the result.
+class EmitNodeXFormMatcher : public Matcher {
+  unsigned Slot;
+  Record *NodeXForm;
+public:
+  EmitNodeXFormMatcher(unsigned slot, Record *nodeXForm)
+    : Matcher(EmitNodeXForm), Slot(slot), NodeXForm(nodeXForm) {}
+  
+  unsigned getSlot() const { return Slot; }
+  Record *getNodeXForm() const { return NodeXForm; }
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == EmitNodeXForm;
+  }
+  
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<EmitNodeXFormMatcher>(M)->Slot == Slot &&
+           cast<EmitNodeXFormMatcher>(M)->NodeXForm == NodeXForm; 
+  }
+  virtual unsigned getHashImpl() const {
+    return Slot ^ ((unsigned)(intptr_t)NodeXForm << 4);
+  }
+};
+  
+/// EmitNodeMatcherCommon - Common class shared between EmitNode and
+/// MorphNodeTo.
+class EmitNodeMatcherCommon : public Matcher {
+  std::string OpcodeName;
+  const SmallVector<MVT::SimpleValueType, 3> VTs;
+  const SmallVector<unsigned, 6> Operands;
+  bool HasChain, HasInFlag, HasOutFlag, HasMemRefs;
+  
+  /// NumFixedArityOperands - If this is a fixed arity node, this is set to -1.
+  /// If this is a varidic node, this is set to the number of fixed arity
+  /// operands in the root of the pattern.  The rest are appended to this node.
+  int NumFixedArityOperands;
+public:
+  EmitNodeMatcherCommon(const std::string &opcodeName,
+                        const MVT::SimpleValueType *vts, unsigned numvts,
+                        const unsigned *operands, unsigned numops,
+                        bool hasChain, bool hasInFlag, bool hasOutFlag,
+                        bool hasmemrefs,
+                        int numfixedarityoperands, bool isMorphNodeTo)
+    : Matcher(isMorphNodeTo ? MorphNodeTo : EmitNode), OpcodeName(opcodeName),
+      VTs(vts, vts+numvts), Operands(operands, operands+numops),
+      HasChain(hasChain), HasInFlag(hasInFlag), HasOutFlag(hasOutFlag),
+      HasMemRefs(hasmemrefs), NumFixedArityOperands(numfixedarityoperands) {}
+  
+  const std::string &getOpcodeName() const { return OpcodeName; }
+  
+  unsigned getNumVTs() const { return VTs.size(); }
+  MVT::SimpleValueType getVT(unsigned i) const {
+    assert(i < VTs.size());
+    return VTs[i];
+  }
+
+  unsigned getNumOperands() const { return Operands.size(); }
+  unsigned getOperand(unsigned i) const {
+    assert(i < Operands.size());
+    return Operands[i];
+  }
+  
+  const SmallVectorImpl<MVT::SimpleValueType> &getVTList() const { return VTs; }
+  const SmallVectorImpl<unsigned> &getOperandList() const { return Operands; }
+
+  
+  bool hasChain() const { return HasChain; }
+  bool hasInFlag() const { return HasInFlag; }
+  bool hasOutFlag() const { return HasOutFlag; }
+  bool hasMemRefs() const { return HasMemRefs; }
+  int getNumFixedArityOperands() const { return NumFixedArityOperands; }
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == EmitNode || N->getKind() == MorphNodeTo;
+  }
+  
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const;
+  virtual unsigned getHashImpl() const;
+};
+  
+/// EmitNodeMatcher - This signals a successful match and generates a node.
+class EmitNodeMatcher : public EmitNodeMatcherCommon {
+  unsigned FirstResultSlot;
+public:
+  EmitNodeMatcher(const std::string &opcodeName,
+                  const MVT::SimpleValueType *vts, unsigned numvts,
+                  const unsigned *operands, unsigned numops,
+                  bool hasChain, bool hasInFlag, bool hasOutFlag,
+                  bool hasmemrefs,
+                  int numfixedarityoperands, unsigned firstresultslot)
+  : EmitNodeMatcherCommon(opcodeName, vts, numvts, operands, numops, hasChain,
+                          hasInFlag, hasOutFlag, hasmemrefs,
+                          numfixedarityoperands, false),
+    FirstResultSlot(firstresultslot) {}
+  
+  unsigned getFirstResultSlot() const { return FirstResultSlot; }
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == EmitNode;
+  }
+  
+};
+  
+class MorphNodeToMatcher : public EmitNodeMatcherCommon {
+  const PatternToMatch &Pattern;
+public:
+  MorphNodeToMatcher(const std::string &opcodeName,
+                     const MVT::SimpleValueType *vts, unsigned numvts,
+                     const unsigned *operands, unsigned numops,
+                     bool hasChain, bool hasInFlag, bool hasOutFlag,
+                     bool hasmemrefs,
+                     int numfixedarityoperands, const PatternToMatch &pattern)
+    : EmitNodeMatcherCommon(opcodeName, vts, numvts, operands, numops, hasChain,
+                            hasInFlag, hasOutFlag, hasmemrefs,
+                            numfixedarityoperands, true),
+      Pattern(pattern) {
+  }
+  
+  const PatternToMatch &getPattern() const { return Pattern; }
+
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == MorphNodeTo;
+  }
+};
+  
+/// MarkFlagResultsMatcher - This node indicates which non-root nodes in the
+/// pattern produce flags.  This allows CompleteMatchMatcher to update them
+/// with the output flag of the resultant code.
+class MarkFlagResultsMatcher : public Matcher {
+  SmallVector<unsigned, 3> FlagResultNodes;
+public:
+  MarkFlagResultsMatcher(const unsigned *nodes, unsigned NumNodes)
+    : Matcher(MarkFlagResults), FlagResultNodes(nodes, nodes+NumNodes) {}
+  
+  unsigned getNumNodes() const { return FlagResultNodes.size(); }
+  
+  unsigned getNode(unsigned i) const {
+    assert(i < FlagResultNodes.size());
+    return FlagResultNodes[i];
+  }  
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == MarkFlagResults;
+  }
+  
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<MarkFlagResultsMatcher>(M)->FlagResultNodes == FlagResultNodes;
+  }
+  virtual unsigned getHashImpl() const;
+};
+
+/// CompleteMatchMatcher - Complete a match by replacing the results of the
+/// pattern with the newly generated nodes.  This also prints a comment
+/// indicating the source and dest patterns.
+class CompleteMatchMatcher : public Matcher {
+  SmallVector<unsigned, 2> Results;
+  const PatternToMatch &Pattern;
+public:
+  CompleteMatchMatcher(const unsigned *results, unsigned numresults,
+                       const PatternToMatch &pattern)
+  : Matcher(CompleteMatch), Results(results, results+numresults),
+    Pattern(pattern) {}
+
+  unsigned getNumResults() const { return Results.size(); }
+  unsigned getResult(unsigned R) const { return Results[R]; }
+  const PatternToMatch &getPattern() const { return Pattern; }
+  
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == CompleteMatch;
+  }
+  
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<CompleteMatchMatcher>(M)->Results == Results &&
+          &cast<CompleteMatchMatcher>(M)->Pattern == &Pattern;
+  }
+  virtual unsigned getHashImpl() const;
+};
+ 
+} // end namespace llvm
+
+#endif
diff --git a/src/LLVM/utils/TableGen/DAGISelMatcherEmitter.cpp b/src/LLVM/utils/TableGen/DAGISelMatcherEmitter.cpp
new file mode 100644
index 0000000..dfbfe80
--- /dev/null
+++ b/src/LLVM/utils/TableGen/DAGISelMatcherEmitter.cpp
@@ -0,0 +1,795 @@
+//===- DAGISelMatcherEmitter.cpp - Matcher Emitter ------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains code to generate C++ code for a matcher.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DAGISelMatcher.h"
+#include "CodeGenDAGPatterns.h"
+#include "Record.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FormattedStream.h"
+using namespace llvm;
+
+enum {
+  CommentIndent = 30
+};
+
+// To reduce generated source code size.
+static cl::opt<bool>
+OmitComments("omit-comments", cl::desc("Do not generate comments"),
+             cl::init(false));
+
+namespace {
+class MatcherTableEmitter {
+  const CodeGenDAGPatterns &CGP;
+  StringMap<unsigned> NodePredicateMap, PatternPredicateMap;
+  std::vector<std::string> NodePredicates, PatternPredicates;
+
+  DenseMap<const ComplexPattern*, unsigned> ComplexPatternMap;
+  std::vector<const ComplexPattern*> ComplexPatterns;
+
+
+  DenseMap<Record*, unsigned> NodeXFormMap;
+  std::vector<Record*> NodeXForms;
+
+public:
+  MatcherTableEmitter(const CodeGenDAGPatterns &cgp) : CGP(cgp) {}
+
+  unsigned EmitMatcherList(const Matcher *N, unsigned Indent,
+                           unsigned StartIdx, formatted_raw_ostream &OS);
+  
+  void EmitPredicateFunctions(formatted_raw_ostream &OS);
+  
+  void EmitHistogram(const Matcher *N, formatted_raw_ostream &OS);
+private:
+  unsigned EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
+                       formatted_raw_ostream &OS);
+  
+  unsigned getNodePredicate(StringRef PredName) {
+    unsigned &Entry = NodePredicateMap[PredName];
+    if (Entry == 0) {
+      NodePredicates.push_back(PredName.str());
+      Entry = NodePredicates.size();
+    }
+    return Entry-1;
+  }
+  unsigned getPatternPredicate(StringRef PredName) {
+    unsigned &Entry = PatternPredicateMap[PredName];
+    if (Entry == 0) {
+      PatternPredicates.push_back(PredName.str());
+      Entry = PatternPredicates.size();
+    }
+    return Entry-1;
+  }
+  
+  unsigned getComplexPat(const ComplexPattern &P) {
+    unsigned &Entry = ComplexPatternMap[&P];
+    if (Entry == 0) {
+      ComplexPatterns.push_back(&P);
+      Entry = ComplexPatterns.size();
+    }
+    return Entry-1;
+  }
+  
+  unsigned getNodeXFormID(Record *Rec) {
+    unsigned &Entry = NodeXFormMap[Rec];
+    if (Entry == 0) {
+      NodeXForms.push_back(Rec);
+      Entry = NodeXForms.size();
+    }
+    return Entry-1;
+  }
+  
+};
+} // end anonymous namespace.
+
+static unsigned GetVBRSize(unsigned Val) {
+  if (Val <= 127) return 1;
+  
+  unsigned NumBytes = 0;
+  while (Val >= 128) {
+    Val >>= 7;
+    ++NumBytes;
+  }
+  return NumBytes+1;
+}
+
+/// EmitVBRValue - Emit the specified value as a VBR, returning the number of
+/// bytes emitted.
+static uint64_t EmitVBRValue(uint64_t Val, raw_ostream &OS) {
+  if (Val <= 127) {
+    OS << Val << ", ";
+    return 1;
+  }
+  
+  uint64_t InVal = Val;
+  unsigned NumBytes = 0;
+  while (Val >= 128) {
+    OS << (Val&127) << "|128,";
+    Val >>= 7;
+    ++NumBytes;
+  }
+  OS << Val;
+  if (!OmitComments)
+    OS << "/*" << InVal << "*/";
+  OS << ", ";
+  return NumBytes+1;
+}
+
+/// EmitMatcherOpcodes - Emit bytes for the specified matcher and return
+/// the number of bytes emitted.
+unsigned MatcherTableEmitter::
+EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
+            formatted_raw_ostream &OS) {
+  OS.PadToColumn(Indent*2);
+  
+  switch (N->getKind()) {
+  case Matcher::Scope: {
+    const ScopeMatcher *SM = cast<ScopeMatcher>(N);
+    assert(SM->getNext() == 0 && "Shouldn't have next after scope");
+    
+    unsigned StartIdx = CurrentIdx;
+    
+    // Emit all of the children.
+    for (unsigned i = 0, e = SM->getNumChildren(); i != e; ++i) {
+      if (i == 0) {
+        OS << "OPC_Scope, ";
+        ++CurrentIdx;
+      } else  {
+        if (!OmitComments) {
+          OS << "/*" << CurrentIdx << "*/";
+          OS.PadToColumn(Indent*2) << "/*Scope*/ ";
+        } else
+          OS.PadToColumn(Indent*2);
+      }
+
+      // We need to encode the child and the offset of the failure code before
+      // emitting either of them.  Handle this by buffering the output into a
+      // string while we get the size.  Unfortunately, the offset of the
+      // children depends on the VBR size of the child, so for large children we
+      // have to iterate a bit.
+      SmallString<128> TmpBuf;
+      unsigned ChildSize = 0;
+      unsigned VBRSize = 0;
+      do {
+        VBRSize = GetVBRSize(ChildSize);
+        
+        TmpBuf.clear();
+        raw_svector_ostream OS(TmpBuf);
+        formatted_raw_ostream FOS(OS);
+        ChildSize = EmitMatcherList(SM->getChild(i), Indent+1,
+                                    CurrentIdx+VBRSize, FOS);
+      } while (GetVBRSize(ChildSize) != VBRSize);
+      
+      assert(ChildSize != 0 && "Should not have a zero-sized child!");
+    
+      CurrentIdx += EmitVBRValue(ChildSize, OS);
+      if (!OmitComments) {
+        OS << "/*->" << CurrentIdx+ChildSize << "*/";
+      
+        if (i == 0)
+          OS.PadToColumn(CommentIndent) << "// " << SM->getNumChildren()
+            << " children in Scope";
+      }
+      
+      OS << '\n' << TmpBuf.str();
+      CurrentIdx += ChildSize;
+    }
+    
+    // Emit a zero as a sentinel indicating end of 'Scope'.
+    if (!OmitComments)
+      OS << "/*" << CurrentIdx << "*/";
+    OS.PadToColumn(Indent*2) << "0, ";
+    if (!OmitComments)
+      OS << "/*End of Scope*/";
+    OS << '\n';
+    return CurrentIdx - StartIdx + 1;
+  }
+      
+  case Matcher::RecordNode:
+    OS << "OPC_RecordNode,";
+    if (!OmitComments)
+      OS.PadToColumn(CommentIndent) << "// #"
+        << cast<RecordMatcher>(N)->getResultNo() << " = "
+        << cast<RecordMatcher>(N)->getWhatFor();
+    OS << '\n';
+    return 1;
+
+  case Matcher::RecordChild:
+    OS << "OPC_RecordChild" << cast<RecordChildMatcher>(N)->getChildNo()
+       << ',';
+    if (!OmitComments)
+      OS.PadToColumn(CommentIndent) << "// #"
+        << cast<RecordChildMatcher>(N)->getResultNo() << " = "
+        << cast<RecordChildMatcher>(N)->getWhatFor();
+    OS << '\n';
+    return 1;
+      
+  case Matcher::RecordMemRef:
+    OS << "OPC_RecordMemRef,\n";
+    return 1;
+      
+  case Matcher::CaptureFlagInput:
+    OS << "OPC_CaptureFlagInput,\n";
+    return 1;
+      
+  case Matcher::MoveChild:
+    OS << "OPC_MoveChild, " << cast<MoveChildMatcher>(N)->getChildNo() << ",\n";
+    return 2;
+      
+  case Matcher::MoveParent:
+    OS << "OPC_MoveParent,\n";
+    return 1;
+      
+  case Matcher::CheckSame:
+    OS << "OPC_CheckSame, "
+       << cast<CheckSameMatcher>(N)->getMatchNumber() << ",\n";
+    return 2;
+
+  case Matcher::CheckPatternPredicate: {
+    StringRef Pred = cast<CheckPatternPredicateMatcher>(N)->getPredicate();
+    OS << "OPC_CheckPatternPredicate, " << getPatternPredicate(Pred) << ',';
+    if (!OmitComments)
+      OS.PadToColumn(CommentIndent) << "// " << Pred;
+    OS << '\n';
+    return 2;
+  }
+  case Matcher::CheckPredicate: {
+    StringRef Pred = cast<CheckPredicateMatcher>(N)->getPredicateName();
+    OS << "OPC_CheckPredicate, " << getNodePredicate(Pred) << ',';
+    if (!OmitComments)
+      OS.PadToColumn(CommentIndent) << "// " << Pred;
+    OS << '\n';
+    return 2;
+  }
+
+  case Matcher::CheckOpcode:
+    OS << "OPC_CheckOpcode, TARGET_OPCODE("
+       << cast<CheckOpcodeMatcher>(N)->getOpcode().getEnumName() << "),\n";
+    return 3;
+      
+  case Matcher::SwitchOpcode:
+  case Matcher::SwitchType: {
+    unsigned StartIdx = CurrentIdx;
+    
+    unsigned NumCases;
+    if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) {
+      OS << "OPC_SwitchOpcode ";
+      NumCases = SOM->getNumCases();
+    } else {
+      OS << "OPC_SwitchType ";
+      NumCases = cast<SwitchTypeMatcher>(N)->getNumCases();
+    }
+
+    if (!OmitComments)
+      OS << "/*" << NumCases << " cases */";
+    OS << ", ";
+    ++CurrentIdx;
+    
+    // For each case we emit the size, then the opcode, then the matcher.
+    for (unsigned i = 0, e = NumCases; i != e; ++i) {
+      const Matcher *Child;
+      unsigned IdxSize;
+      if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) {
+        Child = SOM->getCaseMatcher(i);
+        IdxSize = 2;  // size of opcode in table is 2 bytes.
+      } else {
+        Child = cast<SwitchTypeMatcher>(N)->getCaseMatcher(i);
+        IdxSize = 1;  // size of type in table is 1 byte.
+      }
+      
+      // We need to encode the opcode and the offset of the case code before
+      // emitting the case code.  Handle this by buffering the output into a
+      // string while we get the size.  Unfortunately, the offset of the
+      // children depends on the VBR size of the child, so for large children we
+      // have to iterate a bit.
+      SmallString<128> TmpBuf;
+      unsigned ChildSize = 0;
+      unsigned VBRSize = 0;
+      do {
+        VBRSize = GetVBRSize(ChildSize);
+        
+        TmpBuf.clear();
+        raw_svector_ostream OS(TmpBuf);
+        formatted_raw_ostream FOS(OS);
+        ChildSize = EmitMatcherList(Child, Indent+1, CurrentIdx+VBRSize+IdxSize,
+                                    FOS);
+      } while (GetVBRSize(ChildSize) != VBRSize);
+      
+      assert(ChildSize != 0 && "Should not have a zero-sized child!");
+      
+      if (i != 0) {
+        OS.PadToColumn(Indent*2);
+        if (!OmitComments)
+        OS << (isa<SwitchOpcodeMatcher>(N) ?
+                   "/*SwitchOpcode*/ " : "/*SwitchType*/ ");
+      }
+      
+      // Emit the VBR.
+      CurrentIdx += EmitVBRValue(ChildSize, OS);
+      
+      OS << ' ';
+      if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N))
+        OS << "TARGET_OPCODE(" << SOM->getCaseOpcode(i).getEnumName() << "),";
+      else
+        OS << getEnumName(cast<SwitchTypeMatcher>(N)->getCaseType(i)) << ',';
+
+      CurrentIdx += IdxSize;
+
+      if (!OmitComments)
+        OS << "// ->" << CurrentIdx+ChildSize;
+      OS << '\n';
+      OS << TmpBuf.str();
+      CurrentIdx += ChildSize;
+    }
+
+    // Emit the final zero to terminate the switch.
+    OS.PadToColumn(Indent*2) << "0, ";
+    if (!OmitComments)
+      OS << (isa<SwitchOpcodeMatcher>(N) ?
+             "// EndSwitchOpcode" : "// EndSwitchType");
+
+    OS << '\n';
+    ++CurrentIdx;
+    return CurrentIdx-StartIdx;
+  }
+
+ case Matcher::CheckType:
+    assert(cast<CheckTypeMatcher>(N)->getResNo() == 0 &&
+           "FIXME: Add support for CheckType of resno != 0");
+    OS << "OPC_CheckType, "
+       << getEnumName(cast<CheckTypeMatcher>(N)->getType()) << ",\n";
+    return 2;
+      
+  case Matcher::CheckChildType:
+    OS << "OPC_CheckChild"
+       << cast<CheckChildTypeMatcher>(N)->getChildNo() << "Type, "
+       << getEnumName(cast<CheckChildTypeMatcher>(N)->getType()) << ",\n";
+    return 2;
+      
+  case Matcher::CheckInteger: {
+    OS << "OPC_CheckInteger, ";
+    unsigned Bytes=1+EmitVBRValue(cast<CheckIntegerMatcher>(N)->getValue(), OS);
+    OS << '\n';
+    return Bytes;
+  }
+  case Matcher::CheckCondCode:
+    OS << "OPC_CheckCondCode, ISD::"
+       << cast<CheckCondCodeMatcher>(N)->getCondCodeName() << ",\n";
+    return 2;
+      
+  case Matcher::CheckValueType:
+    OS << "OPC_CheckValueType, MVT::"
+       << cast<CheckValueTypeMatcher>(N)->getTypeName() << ",\n";
+    return 2;
+
+  case Matcher::CheckComplexPat: {
+    const CheckComplexPatMatcher *CCPM = cast<CheckComplexPatMatcher>(N);
+    const ComplexPattern &Pattern = CCPM->getPattern();
+    OS << "OPC_CheckComplexPat, /*CP*/" << getComplexPat(Pattern) << ", /*#*/"
+       << CCPM->getMatchNumber() << ',';
+    
+    if (!OmitComments) {
+      OS.PadToColumn(CommentIndent) << "// " << Pattern.getSelectFunc();
+      OS << ":$" << CCPM->getName();
+      for (unsigned i = 0, e = Pattern.getNumOperands(); i != e; ++i)
+        OS << " #" << CCPM->getFirstResult()+i;
+           
+      if (Pattern.hasProperty(SDNPHasChain))
+        OS << " + chain result";
+    }
+    OS << '\n';
+    return 3;
+  }
+      
+  case Matcher::CheckAndImm: {
+    OS << "OPC_CheckAndImm, ";
+    unsigned Bytes=1+EmitVBRValue(cast<CheckAndImmMatcher>(N)->getValue(), OS);
+    OS << '\n';
+    return Bytes;
+  }
+
+  case Matcher::CheckOrImm: {
+    OS << "OPC_CheckOrImm, ";
+    unsigned Bytes = 1+EmitVBRValue(cast<CheckOrImmMatcher>(N)->getValue(), OS);
+    OS << '\n';
+    return Bytes;
+  }
+      
+  case Matcher::CheckFoldableChainNode:
+    OS << "OPC_CheckFoldableChainNode,\n";
+    return 1;
+      
+  case Matcher::EmitInteger: {
+    int64_t Val = cast<EmitIntegerMatcher>(N)->getValue();
+    OS << "OPC_EmitInteger, "
+       << getEnumName(cast<EmitIntegerMatcher>(N)->getVT()) << ", ";
+    unsigned Bytes = 2+EmitVBRValue(Val, OS);
+    OS << '\n';
+    return Bytes;
+  }
+  case Matcher::EmitStringInteger: {
+    const std::string &Val = cast<EmitStringIntegerMatcher>(N)->getValue();
+    // These should always fit into one byte.
+    OS << "OPC_EmitInteger, "
+      << getEnumName(cast<EmitStringIntegerMatcher>(N)->getVT()) << ", "
+      << Val << ",\n";
+    return 3;
+  }
+      
+  case Matcher::EmitRegister:
+    OS << "OPC_EmitRegister, "
+       << getEnumName(cast<EmitRegisterMatcher>(N)->getVT()) << ", ";
+    if (Record *R = cast<EmitRegisterMatcher>(N)->getReg())
+      OS << getQualifiedName(R) << ",\n";
+    else {
+      OS << "0 ";
+      if (!OmitComments)
+        OS << "/*zero_reg*/";
+      OS << ",\n";
+    }
+    return 3;
+      
+  case Matcher::EmitConvertToTarget:
+    OS << "OPC_EmitConvertToTarget, "
+       << cast<EmitConvertToTargetMatcher>(N)->getSlot() << ",\n";
+    return 2;
+      
+  case Matcher::EmitMergeInputChains: {
+    const EmitMergeInputChainsMatcher *MN =
+      cast<EmitMergeInputChainsMatcher>(N);
+    
+    // Handle the specialized forms OPC_EmitMergeInputChains1_0 and 1_1.
+    if (MN->getNumNodes() == 1 && MN->getNode(0) < 2) {
+      OS << "OPC_EmitMergeInputChains1_" << MN->getNode(0) << ",\n";
+      return 1;
+    }
+    
+    OS << "OPC_EmitMergeInputChains, " << MN->getNumNodes() << ", ";
+    for (unsigned i = 0, e = MN->getNumNodes(); i != e; ++i)
+      OS << MN->getNode(i) << ", ";
+    OS << '\n';
+    return 2+MN->getNumNodes();
+  }
+  case Matcher::EmitCopyToReg:
+    OS << "OPC_EmitCopyToReg, "
+       << cast<EmitCopyToRegMatcher>(N)->getSrcSlot() << ", "
+       << getQualifiedName(cast<EmitCopyToRegMatcher>(N)->getDestPhysReg())
+       << ",\n";
+    return 3;
+  case Matcher::EmitNodeXForm: {
+    const EmitNodeXFormMatcher *XF = cast<EmitNodeXFormMatcher>(N);
+    OS << "OPC_EmitNodeXForm, " << getNodeXFormID(XF->getNodeXForm()) << ", "
+       << XF->getSlot() << ',';
+    if (!OmitComments)
+      OS.PadToColumn(CommentIndent) << "// "<<XF->getNodeXForm()->getName();
+    OS <<'\n';
+    return 3;
+  }
+      
+  case Matcher::EmitNode:
+  case Matcher::MorphNodeTo: {
+    const EmitNodeMatcherCommon *EN = cast<EmitNodeMatcherCommon>(N);
+    OS << (isa<EmitNodeMatcher>(EN) ? "OPC_EmitNode" : "OPC_MorphNodeTo");
+    OS << ", TARGET_OPCODE(" << EN->getOpcodeName() << "), 0";
+    
+    if (EN->hasChain())   OS << "|OPFL_Chain";
+    if (EN->hasInFlag())  OS << "|OPFL_FlagInput";
+    if (EN->hasOutFlag()) OS << "|OPFL_FlagOutput";
+    if (EN->hasMemRefs()) OS << "|OPFL_MemRefs";
+    if (EN->getNumFixedArityOperands() != -1)
+      OS << "|OPFL_Variadic" << EN->getNumFixedArityOperands();
+    OS << ",\n";
+    
+    OS.PadToColumn(Indent*2+4) << EN->getNumVTs();
+    if (!OmitComments)
+      OS << "/*#VTs*/";
+    OS << ", ";
+    for (unsigned i = 0, e = EN->getNumVTs(); i != e; ++i)
+      OS << getEnumName(EN->getVT(i)) << ", ";
+
+    OS << EN->getNumOperands();
+    if (!OmitComments)
+      OS << "/*#Ops*/";
+    OS << ", ";
+    unsigned NumOperandBytes = 0;
+    for (unsigned i = 0, e = EN->getNumOperands(); i != e; ++i)
+      NumOperandBytes += EmitVBRValue(EN->getOperand(i), OS);
+    
+    if (!OmitComments) {
+      // Print the result #'s for EmitNode.
+      if (const EmitNodeMatcher *E = dyn_cast<EmitNodeMatcher>(EN)) {
+        if (unsigned NumResults = EN->getNumVTs()) {
+          OS.PadToColumn(CommentIndent) << "// Results = ";
+          unsigned First = E->getFirstResultSlot();
+          for (unsigned i = 0; i != NumResults; ++i)
+            OS << "#" << First+i << " ";
+        }
+      }
+      OS << '\n';
+
+      if (const MorphNodeToMatcher *SNT = dyn_cast<MorphNodeToMatcher>(N)) {
+        OS.PadToColumn(Indent*2) << "// Src: "
+          << *SNT->getPattern().getSrcPattern() << " - Complexity = " 
+          << SNT->getPattern().getPatternComplexity(CGP) << '\n';
+        OS.PadToColumn(Indent*2) << "// Dst: "
+          << *SNT->getPattern().getDstPattern() << '\n';
+      }
+    } else
+      OS << '\n';
+    
+    return 6+EN->getNumVTs()+NumOperandBytes;
+  }
+  case Matcher::MarkFlagResults: {
+    const MarkFlagResultsMatcher *CFR = cast<MarkFlagResultsMatcher>(N);
+    OS << "OPC_MarkFlagResults, " << CFR->getNumNodes() << ", ";
+    unsigned NumOperandBytes = 0;
+    for (unsigned i = 0, e = CFR->getNumNodes(); i != e; ++i)
+      NumOperandBytes += EmitVBRValue(CFR->getNode(i), OS);
+    OS << '\n';
+    return 2+NumOperandBytes;
+  }
+  case Matcher::CompleteMatch: {
+    const CompleteMatchMatcher *CM = cast<CompleteMatchMatcher>(N);
+    OS << "OPC_CompleteMatch, " << CM->getNumResults() << ", ";
+    unsigned NumResultBytes = 0;
+    for (unsigned i = 0, e = CM->getNumResults(); i != e; ++i)
+      NumResultBytes += EmitVBRValue(CM->getResult(i), OS);
+    OS << '\n';
+    if (!OmitComments) {
+      OS.PadToColumn(Indent*2) << "// Src: "
+        << *CM->getPattern().getSrcPattern() << " - Complexity = " 
+        << CM->getPattern().getPatternComplexity(CGP) << '\n';
+      OS.PadToColumn(Indent*2) << "// Dst: "
+        << *CM->getPattern().getDstPattern();
+    }
+    OS << '\n';
+    return 2 + NumResultBytes;
+  }
+  }
+  assert(0 && "Unreachable");
+  return 0;
+}
+
+/// EmitMatcherList - Emit the bytes for the specified matcher subtree.
+unsigned MatcherTableEmitter::
+EmitMatcherList(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
+                formatted_raw_ostream &OS) {
+  unsigned Size = 0;
+  while (N) {
+    if (!OmitComments)
+      OS << "/*" << CurrentIdx << "*/";
+    unsigned MatcherSize = EmitMatcher(N, Indent, CurrentIdx, OS);
+    Size += MatcherSize;
+    CurrentIdx += MatcherSize;
+    
+    // If there are other nodes in this list, iterate to them, otherwise we're
+    // done.
+    N = N->getNext();
+  }
+  return Size;
+}
+
+void MatcherTableEmitter::EmitPredicateFunctions(formatted_raw_ostream &OS) {
+  // Emit pattern predicates.
+  if (!PatternPredicates.empty()) {
+    OS << "bool CheckPatternPredicate(unsigned PredNo) const {\n";
+    OS << "  switch (PredNo) {\n";
+    OS << "  default: assert(0 && \"Invalid predicate in table?\");\n";
+    for (unsigned i = 0, e = PatternPredicates.size(); i != e; ++i)
+      OS << "  case " << i << ": return "  << PatternPredicates[i] << ";\n";
+    OS << "  }\n";
+    OS << "}\n\n";
+  }
+   
+  // Emit Node predicates.
+  // FIXME: Annoyingly, these are stored by name, which we never even emit. Yay?
+  StringMap<TreePattern*> PFsByName;
+  
+  for (CodeGenDAGPatterns::pf_iterator I = CGP.pf_begin(), E = CGP.pf_end();
+       I != E; ++I)
+    PFsByName[I->first->getName()] = I->second;
+  
+  if (!NodePredicates.empty()) {
+    OS << "bool CheckNodePredicate(SDNode *Node, unsigned PredNo) const {\n";
+    OS << "  switch (PredNo) {\n";
+    OS << "  default: assert(0 && \"Invalid predicate in table?\");\n";
+    for (unsigned i = 0, e = NodePredicates.size(); i != e; ++i) {
+      // FIXME: Storing this by name is horrible.
+      TreePattern *P =PFsByName[NodePredicates[i].substr(strlen("Predicate_"))];
+      assert(P && "Unknown name?");
+      
+      // Emit the predicate code corresponding to this pattern.
+      std::string Code = P->getRecord()->getValueAsCode("Predicate");
+      assert(!Code.empty() && "No code in this predicate");
+      OS << "  case " << i << ": { // " << NodePredicates[i] << '\n';
+      std::string ClassName;
+      if (P->getOnlyTree()->isLeaf())
+        ClassName = "SDNode";
+      else
+        ClassName =
+          CGP.getSDNodeInfo(P->getOnlyTree()->getOperator()).getSDClassName();
+      if (ClassName == "SDNode")
+        OS << "    SDNode *N = Node;\n";
+      else
+        OS << "    " << ClassName << "*N = cast<" << ClassName << ">(Node);\n";
+      OS << Code << "\n  }\n";
+    }
+    OS << "  }\n";
+    OS << "}\n\n";
+  }
+  
+  // Emit CompletePattern matchers.
+  // FIXME: This should be const.
+  if (!ComplexPatterns.empty()) {
+    OS << "bool CheckComplexPattern(SDNode *Root, SDValue N,\n";
+    OS << "      unsigned PatternNo, SmallVectorImpl<SDValue> &Result) {\n";
+    OS << "  unsigned NextRes = Result.size();\n";
+    OS << "  switch (PatternNo) {\n";
+    OS << "  default: assert(0 && \"Invalid pattern # in table?\");\n";
+    for (unsigned i = 0, e = ComplexPatterns.size(); i != e; ++i) {
+      const ComplexPattern &P = *ComplexPatterns[i];
+      unsigned NumOps = P.getNumOperands();
+
+      if (P.hasProperty(SDNPHasChain))
+        ++NumOps;  // Get the chained node too.
+      
+      OS << "  case " << i << ":\n";
+      OS << "    Result.resize(NextRes+" << NumOps << ");\n";
+      OS << "    return "  << P.getSelectFunc();
+
+      OS << "(Root, N";
+      for (unsigned i = 0; i != NumOps; ++i)
+        OS << ", Result[NextRes+" << i << ']';
+      OS << ");\n";
+    }
+    OS << "  }\n";
+    OS << "}\n\n";
+  }
+  
+  
+  // Emit SDNodeXForm handlers.
+  // FIXME: This should be const.
+  if (!NodeXForms.empty()) {
+    OS << "SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) {\n";
+    OS << "  switch (XFormNo) {\n";
+    OS << "  default: assert(0 && \"Invalid xform # in table?\");\n";
+    
+    // FIXME: The node xform could take SDValue's instead of SDNode*'s.
+    for (unsigned i = 0, e = NodeXForms.size(); i != e; ++i) {
+      const CodeGenDAGPatterns::NodeXForm &Entry =
+        CGP.getSDNodeTransform(NodeXForms[i]);
+      
+      Record *SDNode = Entry.first;
+      const std::string &Code = Entry.second;
+      
+      OS << "  case " << i << ": {  ";
+      if (!OmitComments)
+        OS << "// " << NodeXForms[i]->getName();
+      OS << '\n';
+      
+      std::string ClassName = CGP.getSDNodeInfo(SDNode).getSDClassName();
+      if (ClassName == "SDNode")
+        OS << "    SDNode *N = V.getNode();\n";
+      else
+        OS << "    " << ClassName << " *N = cast<" << ClassName
+           << ">(V.getNode());\n";
+      OS << Code << "\n  }\n";
+    }
+    OS << "  }\n";
+    OS << "}\n\n";
+  }
+}
+
+static void BuildHistogram(const Matcher *M, std::vector<unsigned> &OpcodeFreq){
+  for (; M != 0; M = M->getNext()) {
+    // Count this node.
+    if (unsigned(M->getKind()) >= OpcodeFreq.size())
+      OpcodeFreq.resize(M->getKind()+1);
+    OpcodeFreq[M->getKind()]++;
+  
+    // Handle recursive nodes.
+    if (const ScopeMatcher *SM = dyn_cast<ScopeMatcher>(M)) {
+      for (unsigned i = 0, e = SM->getNumChildren(); i != e; ++i)
+        BuildHistogram(SM->getChild(i), OpcodeFreq);
+    } else if (const SwitchOpcodeMatcher *SOM = 
+                 dyn_cast<SwitchOpcodeMatcher>(M)) {
+      for (unsigned i = 0, e = SOM->getNumCases(); i != e; ++i)
+        BuildHistogram(SOM->getCaseMatcher(i), OpcodeFreq);
+    } else if (const SwitchTypeMatcher *STM = dyn_cast<SwitchTypeMatcher>(M)) {
+      for (unsigned i = 0, e = STM->getNumCases(); i != e; ++i)
+        BuildHistogram(STM->getCaseMatcher(i), OpcodeFreq);
+    }
+  }
+}
+
+void MatcherTableEmitter::EmitHistogram(const Matcher *M,
+                                        formatted_raw_ostream &OS) {
+  if (OmitComments)
+    return;
+  
+  std::vector<unsigned> OpcodeFreq;
+  BuildHistogram(M, OpcodeFreq);
+  
+  OS << "  // Opcode Histogram:\n";
+  for (unsigned i = 0, e = OpcodeFreq.size(); i != e; ++i) {
+    OS << "  // #";
+    switch ((Matcher::KindTy)i) {
+    case Matcher::Scope: OS << "OPC_Scope"; break; 
+    case Matcher::RecordNode: OS << "OPC_RecordNode"; break; 
+    case Matcher::RecordChild: OS << "OPC_RecordChild"; break;
+    case Matcher::RecordMemRef: OS << "OPC_RecordMemRef"; break;
+    case Matcher::CaptureFlagInput: OS << "OPC_CaptureFlagInput"; break;
+    case Matcher::MoveChild: OS << "OPC_MoveChild"; break;
+    case Matcher::MoveParent: OS << "OPC_MoveParent"; break;
+    case Matcher::CheckSame: OS << "OPC_CheckSame"; break;
+    case Matcher::CheckPatternPredicate:
+      OS << "OPC_CheckPatternPredicate"; break;
+    case Matcher::CheckPredicate: OS << "OPC_CheckPredicate"; break;
+    case Matcher::CheckOpcode: OS << "OPC_CheckOpcode"; break;
+    case Matcher::SwitchOpcode: OS << "OPC_SwitchOpcode"; break;
+    case Matcher::CheckType: OS << "OPC_CheckType"; break;
+    case Matcher::SwitchType: OS << "OPC_SwitchType"; break;
+    case Matcher::CheckChildType: OS << "OPC_CheckChildType"; break;
+    case Matcher::CheckInteger: OS << "OPC_CheckInteger"; break;
+    case Matcher::CheckCondCode: OS << "OPC_CheckCondCode"; break;
+    case Matcher::CheckValueType: OS << "OPC_CheckValueType"; break;
+    case Matcher::CheckComplexPat: OS << "OPC_CheckComplexPat"; break;
+    case Matcher::CheckAndImm: OS << "OPC_CheckAndImm"; break;
+    case Matcher::CheckOrImm: OS << "OPC_CheckOrImm"; break;
+    case Matcher::CheckFoldableChainNode:
+      OS << "OPC_CheckFoldableChainNode"; break;
+    case Matcher::EmitInteger: OS << "OPC_EmitInteger"; break;
+    case Matcher::EmitStringInteger: OS << "OPC_EmitStringInteger"; break;
+    case Matcher::EmitRegister: OS << "OPC_EmitRegister"; break;
+    case Matcher::EmitConvertToTarget: OS << "OPC_EmitConvertToTarget"; break;
+    case Matcher::EmitMergeInputChains: OS << "OPC_EmitMergeInputChains"; break;
+    case Matcher::EmitCopyToReg: OS << "OPC_EmitCopyToReg"; break;
+    case Matcher::EmitNode: OS << "OPC_EmitNode"; break;
+    case Matcher::MorphNodeTo: OS << "OPC_MorphNodeTo"; break;
+    case Matcher::EmitNodeXForm: OS << "OPC_EmitNodeXForm"; break;
+    case Matcher::MarkFlagResults: OS << "OPC_MarkFlagResults"; break;
+    case Matcher::CompleteMatch: OS << "OPC_CompleteMatch"; break;    
+    }
+    
+    OS.PadToColumn(40) << " = " << OpcodeFreq[i] << '\n';
+  }
+  OS << '\n';
+}
+
+
+void llvm::EmitMatcherTable(const Matcher *TheMatcher,
+                            const CodeGenDAGPatterns &CGP, raw_ostream &O) {
+  formatted_raw_ostream OS(O);
+  
+  OS << "// The main instruction selector code.\n";
+  OS << "SDNode *SelectCode(SDNode *N) {\n";
+
+  MatcherTableEmitter MatcherEmitter(CGP);
+
+  OS << "  // Opcodes are emitted as 2 bytes, TARGET_OPCODE handles this.\n";
+  OS << "  #define TARGET_OPCODE(X) X & 255, unsigned(X) >> 8\n";
+  OS << "  static const unsigned char MatcherTable[] = {\n";
+  unsigned TotalSize = MatcherEmitter.EmitMatcherList(TheMatcher, 5, 0, OS);
+  OS << "    0\n  }; // Total Array size is " << (TotalSize+1) << " bytes\n\n";
+  
+  MatcherEmitter.EmitHistogram(TheMatcher, OS);
+  
+  OS << "  #undef TARGET_OPCODE\n";
+  OS << "  return SelectCodeCommon(N, MatcherTable,sizeof(MatcherTable));\n}\n";
+  OS << '\n';
+  
+  // Next up, emit the function for node and pattern predicates:
+  MatcherEmitter.EmitPredicateFunctions(OS);
+}
diff --git a/src/LLVM/utils/TableGen/DAGISelMatcherGen.cpp b/src/LLVM/utils/TableGen/DAGISelMatcherGen.cpp
new file mode 100644
index 0000000..aba6636
--- /dev/null
+++ b/src/LLVM/utils/TableGen/DAGISelMatcherGen.cpp
@@ -0,0 +1,910 @@
+//===- DAGISelMatcherGen.cpp - Matcher generator --------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DAGISelMatcher.h"
+#include "CodeGenDAGPatterns.h"
+#include "Record.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include <utility>
+using namespace llvm;
+
+
+/// getRegisterValueType - Look up and return the ValueType of the specified
+/// register. If the register is a member of multiple register classes which
+/// have different associated types, return MVT::Other.
+static MVT::SimpleValueType getRegisterValueType(Record *R,
+                                                 const CodeGenTarget &T) {
+  bool FoundRC = false;
+  MVT::SimpleValueType VT = MVT::Other;
+  const std::vector<CodeGenRegisterClass> &RCs = T.getRegisterClasses();
+  std::vector<Record*>::const_iterator Element;
+  
+  for (unsigned rc = 0, e = RCs.size(); rc != e; ++rc) {
+    const CodeGenRegisterClass &RC = RCs[rc];
+    if (!std::count(RC.Elements.begin(), RC.Elements.end(), R))
+      continue;
+    
+    if (!FoundRC) {
+      FoundRC = true;
+      VT = RC.getValueTypeNum(0);
+      continue;
+    }
+
+    // If this occurs in multiple register classes, they all have to agree.
+    assert(VT == RC.getValueTypeNum(0));
+  }
+  return VT;
+}
+
+
+namespace {
+  class MatcherGen {
+    const PatternToMatch &Pattern;
+    const CodeGenDAGPatterns &CGP;
+    
+    /// PatWithNoTypes - This is a clone of Pattern.getSrcPattern() that starts
+    /// out with all of the types removed.  This allows us to insert type checks
+    /// as we scan the tree.
+    TreePatternNode *PatWithNoTypes;
+    
+    /// VariableMap - A map from variable names ('$dst') to the recorded operand
+    /// number that they were captured as.  These are biased by 1 to make
+    /// insertion easier.
+    StringMap<unsigned> VariableMap;
+    
+    /// NextRecordedOperandNo - As we emit opcodes to record matched values in
+    /// the RecordedNodes array, this keeps track of which slot will be next to
+    /// record into.
+    unsigned NextRecordedOperandNo;
+    
+    /// MatchedChainNodes - This maintains the position in the recorded nodes
+    /// array of all of the recorded input nodes that have chains.
+    SmallVector<unsigned, 2> MatchedChainNodes;
+
+    /// MatchedFlagResultNodes - This maintains the position in the recorded
+    /// nodes array of all of the recorded input nodes that have flag results.
+    SmallVector<unsigned, 2> MatchedFlagResultNodes;
+    
+    /// MatchedComplexPatterns - This maintains a list of all of the
+    /// ComplexPatterns that we need to check.  The patterns are known to have
+    /// names which were recorded.  The second element of each pair is the first
+    /// slot number that the OPC_CheckComplexPat opcode drops the matched
+    /// results into.
+    SmallVector<std::pair<const TreePatternNode*,
+                          unsigned>, 2> MatchedComplexPatterns;
+    
+    /// PhysRegInputs - List list has an entry for each explicitly specified
+    /// physreg input to the pattern.  The first elt is the Register node, the
+    /// second is the recorded slot number the input pattern match saved it in.
+    SmallVector<std::pair<Record*, unsigned>, 2> PhysRegInputs;
+    
+    /// Matcher - This is the top level of the generated matcher, the result.
+    Matcher *TheMatcher;
+    
+    /// CurPredicate - As we emit matcher nodes, this points to the latest check
+    /// which should have future checks stuck into its Next position.
+    Matcher *CurPredicate;
+  public:
+    MatcherGen(const PatternToMatch &pattern, const CodeGenDAGPatterns &cgp);
+    
+    ~MatcherGen() {
+      delete PatWithNoTypes;
+    }
+    
+    bool EmitMatcherCode(unsigned Variant);
+    void EmitResultCode();
+    
+    Matcher *GetMatcher() const { return TheMatcher; }
+    Matcher *GetCurPredicate() const { return CurPredicate; }
+  private:
+    void AddMatcher(Matcher *NewNode);
+    void InferPossibleTypes();
+    
+    // Matcher Generation.
+    void EmitMatchCode(const TreePatternNode *N, TreePatternNode *NodeNoTypes);
+    void EmitLeafMatchCode(const TreePatternNode *N);
+    void EmitOperatorMatchCode(const TreePatternNode *N,
+                               TreePatternNode *NodeNoTypes);
+    
+    // Result Code Generation.
+    unsigned getNamedArgumentSlot(StringRef Name) {
+      unsigned VarMapEntry = VariableMap[Name];
+      assert(VarMapEntry != 0 &&
+             "Variable referenced but not defined and not caught earlier!");
+      return VarMapEntry-1;
+    }
+
+    /// GetInstPatternNode - Get the pattern for an instruction.
+    const TreePatternNode *GetInstPatternNode(const DAGInstruction &Ins,
+                                              const TreePatternNode *N);
+    
+    void EmitResultOperand(const TreePatternNode *N,
+                           SmallVectorImpl<unsigned> &ResultOps);
+    void EmitResultOfNamedOperand(const TreePatternNode *N,
+                                  SmallVectorImpl<unsigned> &ResultOps);
+    void EmitResultLeafAsOperand(const TreePatternNode *N,
+                                 SmallVectorImpl<unsigned> &ResultOps);
+    void EmitResultInstructionAsOperand(const TreePatternNode *N,
+                                        SmallVectorImpl<unsigned> &ResultOps);
+    void EmitResultSDNodeXFormAsOperand(const TreePatternNode *N,
+                                        SmallVectorImpl<unsigned> &ResultOps);
+    };
+  
+} // end anon namespace.
+
+MatcherGen::MatcherGen(const PatternToMatch &pattern,
+                       const CodeGenDAGPatterns &cgp)
+: Pattern(pattern), CGP(cgp), NextRecordedOperandNo(0),
+  TheMatcher(0), CurPredicate(0) {
+  // We need to produce the matcher tree for the patterns source pattern.  To do
+  // this we need to match the structure as well as the types.  To do the type
+  // matching, we want to figure out the fewest number of type checks we need to
+  // emit.  For example, if there is only one integer type supported by a
+  // target, there should be no type comparisons at all for integer patterns!
+  //
+  // To figure out the fewest number of type checks needed, clone the pattern,
+  // remove the types, then perform type inference on the pattern as a whole.
+  // If there are unresolved types, emit an explicit check for those types,
+  // apply the type to the tree, then rerun type inference.  Iterate until all
+  // types are resolved.
+  //
+  PatWithNoTypes = Pattern.getSrcPattern()->clone();
+  PatWithNoTypes->RemoveAllTypes();
+    
+  // If there are types that are manifestly known, infer them.
+  InferPossibleTypes();
+}
+
+/// InferPossibleTypes - As we emit the pattern, we end up generating type
+/// checks and applying them to the 'PatWithNoTypes' tree.  As we do this, we
+/// want to propagate implied types as far throughout the tree as possible so
+/// that we avoid doing redundant type checks.  This does the type propagation.
+void MatcherGen::InferPossibleTypes() {
+  // TP - Get *SOME* tree pattern, we don't care which.  It is only used for
+  // diagnostics, which we know are impossible at this point.
+  TreePattern &TP = *CGP.pf_begin()->second;
+  
+  try {
+    bool MadeChange = true;
+    while (MadeChange)
+      MadeChange = PatWithNoTypes->ApplyTypeConstraints(TP,
+                                                true/*Ignore reg constraints*/);
+  } catch (...) {
+    errs() << "Type constraint application shouldn't fail!";
+    abort();
+  }
+}
+
+
+/// AddMatcher - Add a matcher node to the current graph we're building. 
+void MatcherGen::AddMatcher(Matcher *NewNode) {
+  if (CurPredicate != 0)
+    CurPredicate->setNext(NewNode);
+  else
+    TheMatcher = NewNode;
+  CurPredicate = NewNode;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Pattern Match Generation
+//===----------------------------------------------------------------------===//
+
+/// EmitLeafMatchCode - Generate matching code for leaf nodes.
+void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
+  assert(N->isLeaf() && "Not a leaf?");
+  
+  // Direct match against an integer constant.
+  if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
+    // If this is the root of the dag we're matching, we emit a redundant opcode
+    // check to ensure that this gets folded into the normal top-level
+    // OpcodeSwitch.
+    if (N == Pattern.getSrcPattern()) {
+      const SDNodeInfo &NI = CGP.getSDNodeInfo(CGP.getSDNodeNamed("imm"));
+      AddMatcher(new CheckOpcodeMatcher(NI));
+    }
+
+    return AddMatcher(new CheckIntegerMatcher(II->getValue()));
+  }
+  
+  DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue());
+  if (DI == 0) {
+    errs() << "Unknown leaf kind: " << *DI << "\n";
+    abort();
+  }
+  
+  Record *LeafRec = DI->getDef();
+  if (// Handle register references.  Nothing to do here, they always match.
+      LeafRec->isSubClassOf("RegisterClass") || 
+      LeafRec->isSubClassOf("PointerLikeRegClass") ||
+      LeafRec->isSubClassOf("SubRegIndex") ||
+      // Place holder for SRCVALUE nodes. Nothing to do here.
+      LeafRec->getName() == "srcvalue")
+    return;
+
+  // If we have a physreg reference like (mul gpr:$src, EAX) then we need to
+  // record the register 
+  if (LeafRec->isSubClassOf("Register")) {
+    AddMatcher(new RecordMatcher("physreg input "+LeafRec->getName(),
+                                 NextRecordedOperandNo));
+    PhysRegInputs.push_back(std::make_pair(LeafRec, NextRecordedOperandNo++));
+    return;
+  }
+  
+  if (LeafRec->isSubClassOf("ValueType"))
+    return AddMatcher(new CheckValueTypeMatcher(LeafRec->getName()));
+  
+  if (LeafRec->isSubClassOf("CondCode"))
+    return AddMatcher(new CheckCondCodeMatcher(LeafRec->getName()));
+  
+  if (LeafRec->isSubClassOf("ComplexPattern")) {
+    // We can't model ComplexPattern uses that don't have their name taken yet.
+    // The OPC_CheckComplexPattern operation implicitly records the results.
+    if (N->getName().empty()) {
+      errs() << "We expect complex pattern uses to have names: " << *N << "\n";
+      exit(1);
+    }
+
+    // Remember this ComplexPattern so that we can emit it after all the other
+    // structural matches are done.
+    MatchedComplexPatterns.push_back(std::make_pair(N, 0));
+    return;
+  }
+  
+  errs() << "Unknown leaf kind: " << *N << "\n";
+  abort();
+}
+
+void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
+                                       TreePatternNode *NodeNoTypes) {
+  assert(!N->isLeaf() && "Not an operator?");
+  const SDNodeInfo &CInfo = CGP.getSDNodeInfo(N->getOperator());
+  
+  // If this is an 'and R, 1234' where the operation is AND/OR and the RHS is
+  // a constant without a predicate fn that has more that one bit set, handle
+  // this as a special case.  This is usually for targets that have special
+  // handling of certain large constants (e.g. alpha with it's 8/16/32-bit
+  // handling stuff).  Using these instructions is often far more efficient
+  // than materializing the constant.  Unfortunately, both the instcombiner
+  // and the dag combiner can often infer that bits are dead, and thus drop
+  // them from the mask in the dag.  For example, it might turn 'AND X, 255'
+  // into 'AND X, 254' if it knows the low bit is set.  Emit code that checks
+  // to handle this.
+  if ((N->getOperator()->getName() == "and" || 
+       N->getOperator()->getName() == "or") &&
+      N->getChild(1)->isLeaf() && N->getChild(1)->getPredicateFns().empty() &&
+      N->getPredicateFns().empty()) {
+    if (IntInit *II = dynamic_cast<IntInit*>(N->getChild(1)->getLeafValue())) {
+      if (!isPowerOf2_32(II->getValue())) {  // Don't bother with single bits.
+        // If this is at the root of the pattern, we emit a redundant
+        // CheckOpcode so that the following checks get factored properly under
+        // a single opcode check.
+        if (N == Pattern.getSrcPattern())
+          AddMatcher(new CheckOpcodeMatcher(CInfo));
+
+        // Emit the CheckAndImm/CheckOrImm node.
+        if (N->getOperator()->getName() == "and")
+          AddMatcher(new CheckAndImmMatcher(II->getValue()));
+        else
+          AddMatcher(new CheckOrImmMatcher(II->getValue()));
+
+        // Match the LHS of the AND as appropriate.
+        AddMatcher(new MoveChildMatcher(0));
+        EmitMatchCode(N->getChild(0), NodeNoTypes->getChild(0));
+        AddMatcher(new MoveParentMatcher());
+        return;
+      }
+    }
+  }
+  
+  // Check that the current opcode lines up.
+  AddMatcher(new CheckOpcodeMatcher(CInfo));
+  
+  // If this node has memory references (i.e. is a load or store), tell the
+  // interpreter to capture them in the memref array.
+  if (N->NodeHasProperty(SDNPMemOperand, CGP))
+    AddMatcher(new RecordMemRefMatcher());
+  
+  // If this node has a chain, then the chain is operand #0 is the SDNode, and
+  // the child numbers of the node are all offset by one.
+  unsigned OpNo = 0;
+  if (N->NodeHasProperty(SDNPHasChain, CGP)) {
+    // Record the node and remember it in our chained nodes list.
+    AddMatcher(new RecordMatcher("'" + N->getOperator()->getName() +
+                                         "' chained node",
+                                 NextRecordedOperandNo));
+    // Remember all of the input chains our pattern will match.
+    MatchedChainNodes.push_back(NextRecordedOperandNo++);
+    
+    // Don't look at the input chain when matching the tree pattern to the
+    // SDNode.
+    OpNo = 1;
+
+    // If this node is not the root and the subtree underneath it produces a
+    // chain, then the result of matching the node is also produce a chain.
+    // Beyond that, this means that we're also folding (at least) the root node
+    // into the node that produce the chain (for example, matching
+    // "(add reg, (load ptr))" as a add_with_memory on X86).  This is
+    // problematic, if the 'reg' node also uses the load (say, its chain).
+    // Graphically:
+    //
+    //         [LD]
+    //         ^  ^
+    //         |  \                              DAG's like cheese.
+    //        /    |
+    //       /    [YY]
+    //       |     ^
+    //      [XX]--/
+    //
+    // It would be invalid to fold XX and LD.  In this case, folding the two
+    // nodes together would induce a cycle in the DAG, making it a 'cyclic DAG'
+    // To prevent this, we emit a dynamic check for legality before allowing
+    // this to be folded.
+    //
+    const TreePatternNode *Root = Pattern.getSrcPattern();
+    if (N != Root) {                             // Not the root of the pattern.
+      // If there is a node between the root and this node, then we definitely
+      // need to emit the check.
+      bool NeedCheck = !Root->hasChild(N);
+      
+      // If it *is* an immediate child of the root, we can still need a check if
+      // the root SDNode has multiple inputs.  For us, this means that it is an
+      // intrinsic, has multiple operands, or has other inputs like chain or
+      // flag).
+      if (!NeedCheck) {
+        const SDNodeInfo &PInfo = CGP.getSDNodeInfo(Root->getOperator());
+        NeedCheck =
+          Root->getOperator() == CGP.get_intrinsic_void_sdnode() ||
+          Root->getOperator() == CGP.get_intrinsic_w_chain_sdnode() ||
+          Root->getOperator() == CGP.get_intrinsic_wo_chain_sdnode() ||
+          PInfo.getNumOperands() > 1 ||
+          PInfo.hasProperty(SDNPHasChain) ||
+          PInfo.hasProperty(SDNPInFlag) ||
+          PInfo.hasProperty(SDNPOptInFlag);
+      }
+      
+      if (NeedCheck)
+        AddMatcher(new CheckFoldableChainNodeMatcher());
+    }
+  }
+
+  // If this node has an output flag and isn't the root, remember it.
+  if (N->NodeHasProperty(SDNPOutFlag, CGP) && 
+      N != Pattern.getSrcPattern()) {
+    // TODO: This redundantly records nodes with both flags and chains.
+    
+    // Record the node and remember it in our chained nodes list.
+    AddMatcher(new RecordMatcher("'" + N->getOperator()->getName() +
+                                         "' flag output node",
+                                 NextRecordedOperandNo));
+    // Remember all of the nodes with output flags our pattern will match.
+    MatchedFlagResultNodes.push_back(NextRecordedOperandNo++);
+  }
+  
+  // If this node is known to have an input flag or if it *might* have an input
+  // flag, capture it as the flag input of the pattern.
+  if (N->NodeHasProperty(SDNPOptInFlag, CGP) ||
+      N->NodeHasProperty(SDNPInFlag, CGP))
+    AddMatcher(new CaptureFlagInputMatcher());
+      
+  for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
+    // Get the code suitable for matching this child.  Move to the child, check
+    // it then move back to the parent.
+    AddMatcher(new MoveChildMatcher(OpNo));
+    EmitMatchCode(N->getChild(i), NodeNoTypes->getChild(i));
+    AddMatcher(new MoveParentMatcher());
+  }
+}
+
+
+void MatcherGen::EmitMatchCode(const TreePatternNode *N,
+                               TreePatternNode *NodeNoTypes) {
+  // If N and NodeNoTypes don't agree on a type, then this is a case where we
+  // need to do a type check.  Emit the check, apply the tyep to NodeNoTypes and
+  // reinfer any correlated types.
+  SmallVector<unsigned, 2> ResultsToTypeCheck;
+  
+  for (unsigned i = 0, e = NodeNoTypes->getNumTypes(); i != e; ++i) {
+    if (NodeNoTypes->getExtType(i) == N->getExtType(i)) continue;
+    NodeNoTypes->setType(i, N->getExtType(i));
+    InferPossibleTypes();
+    ResultsToTypeCheck.push_back(i);
+  }
+  
+  // If this node has a name associated with it, capture it in VariableMap. If
+  // we already saw this in the pattern, emit code to verify dagness.
+  if (!N->getName().empty()) {
+    unsigned &VarMapEntry = VariableMap[N->getName()];
+    if (VarMapEntry == 0) {
+      // If it is a named node, we must emit a 'Record' opcode.
+      AddMatcher(new RecordMatcher("$" + N->getName(), NextRecordedOperandNo));
+      VarMapEntry = ++NextRecordedOperandNo;
+    } else {
+      // If we get here, this is a second reference to a specific name.  Since
+      // we already have checked that the first reference is valid, we don't
+      // have to recursively match it, just check that it's the same as the
+      // previously named thing.
+      AddMatcher(new CheckSameMatcher(VarMapEntry-1));
+      return;
+    }
+  }
+  
+  if (N->isLeaf())
+    EmitLeafMatchCode(N);
+  else
+    EmitOperatorMatchCode(N, NodeNoTypes);
+  
+  // If there are node predicates for this node, generate their checks.
+  for (unsigned i = 0, e = N->getPredicateFns().size(); i != e; ++i)
+    AddMatcher(new CheckPredicateMatcher(N->getPredicateFns()[i]));
+  
+  for (unsigned i = 0, e = ResultsToTypeCheck.size(); i != e; ++i)
+    AddMatcher(new CheckTypeMatcher(N->getType(ResultsToTypeCheck[i]),
+                                    ResultsToTypeCheck[i]));
+}
+
+/// EmitMatcherCode - Generate the code that matches the predicate of this
+/// pattern for the specified Variant.  If the variant is invalid this returns
+/// true and does not generate code, if it is valid, it returns false.
+bool MatcherGen::EmitMatcherCode(unsigned Variant) {
+  // If the root of the pattern is a ComplexPattern and if it is specified to
+  // match some number of root opcodes, these are considered to be our variants.
+  // Depending on which variant we're generating code for, emit the root opcode
+  // check.
+  if (const ComplexPattern *CP =
+                   Pattern.getSrcPattern()->getComplexPatternInfo(CGP)) {
+    const std::vector<Record*> &OpNodes = CP->getRootNodes();
+    assert(!OpNodes.empty() &&"Complex Pattern must specify what it can match");
+    if (Variant >= OpNodes.size()) return true;
+    
+    AddMatcher(new CheckOpcodeMatcher(CGP.getSDNodeInfo(OpNodes[Variant])));
+  } else {
+    if (Variant != 0) return true;
+  }
+    
+  // Emit the matcher for the pattern structure and types.
+  EmitMatchCode(Pattern.getSrcPattern(), PatWithNoTypes);
+  
+  // If the pattern has a predicate on it (e.g. only enabled when a subtarget
+  // feature is around, do the check).
+  if (!Pattern.getPredicateCheck().empty())
+    AddMatcher(new CheckPatternPredicateMatcher(Pattern.getPredicateCheck()));
+  
+  // Now that we've completed the structural type match, emit any ComplexPattern
+  // checks (e.g. addrmode matches).  We emit this after the structural match
+  // because they are generally more expensive to evaluate and more difficult to
+  // factor.
+  for (unsigned i = 0, e = MatchedComplexPatterns.size(); i != e; ++i) {
+    const TreePatternNode *N = MatchedComplexPatterns[i].first;
+    
+    // Remember where the results of this match get stuck.
+    MatchedComplexPatterns[i].second = NextRecordedOperandNo;
+
+    // Get the slot we recorded the value in from the name on the node.
+    unsigned RecNodeEntry = VariableMap[N->getName()];
+    assert(!N->getName().empty() && RecNodeEntry &&
+           "Complex pattern should have a name and slot");
+    --RecNodeEntry;  // Entries in VariableMap are biased.
+    
+    const ComplexPattern &CP =
+      CGP.getComplexPattern(((DefInit*)N->getLeafValue())->getDef());
+    
+    // Emit a CheckComplexPat operation, which does the match (aborting if it
+    // fails) and pushes the matched operands onto the recorded nodes list.
+    AddMatcher(new CheckComplexPatMatcher(CP, RecNodeEntry,
+                                          N->getName(), NextRecordedOperandNo));
+    
+    // Record the right number of operands.
+    NextRecordedOperandNo += CP.getNumOperands();
+    if (CP.hasProperty(SDNPHasChain)) {
+      // If the complex pattern has a chain, then we need to keep track of the
+      // fact that we just recorded a chain input.  The chain input will be
+      // matched as the last operand of the predicate if it was successful.
+      ++NextRecordedOperandNo; // Chained node operand.
+    
+      // It is the last operand recorded.
+      assert(NextRecordedOperandNo > 1 &&
+             "Should have recorded input/result chains at least!");
+      MatchedChainNodes.push_back(NextRecordedOperandNo-1);
+    }
+    
+    // TODO: Complex patterns can't have output flags, if they did, we'd want
+    // to record them.
+  }
+  
+  return false;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Node Result Generation
+//===----------------------------------------------------------------------===//
+
+void MatcherGen::EmitResultOfNamedOperand(const TreePatternNode *N,
+                                          SmallVectorImpl<unsigned> &ResultOps){
+  assert(!N->getName().empty() && "Operand not named!");
+  
+  // A reference to a complex pattern gets all of the results of the complex
+  // pattern's match.
+  if (const ComplexPattern *CP = N->getComplexPatternInfo(CGP)) {
+    unsigned SlotNo = 0;
+    for (unsigned i = 0, e = MatchedComplexPatterns.size(); i != e; ++i)
+      if (MatchedComplexPatterns[i].first->getName() == N->getName()) {
+        SlotNo = MatchedComplexPatterns[i].second;
+        break;
+      }
+    assert(SlotNo != 0 && "Didn't get a slot number assigned?");
+    
+    // The first slot entry is the node itself, the subsequent entries are the
+    // matched values.
+    for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
+      ResultOps.push_back(SlotNo+i);
+    return;
+  }
+
+  unsigned SlotNo = getNamedArgumentSlot(N->getName());
+
+  // If this is an 'imm' or 'fpimm' node, make sure to convert it to the target
+  // version of the immediate so that it doesn't get selected due to some other
+  // node use.
+  if (!N->isLeaf()) {
+    StringRef OperatorName = N->getOperator()->getName();
+    if (OperatorName == "imm" || OperatorName == "fpimm") {
+      AddMatcher(new EmitConvertToTargetMatcher(SlotNo));
+      ResultOps.push_back(NextRecordedOperandNo++);
+      return;
+    }
+  }
+  
+  ResultOps.push_back(SlotNo);
+}
+
+void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N,
+                                         SmallVectorImpl<unsigned> &ResultOps) {
+  assert(N->isLeaf() && "Must be a leaf");
+  
+  if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
+    AddMatcher(new EmitIntegerMatcher(II->getValue(), N->getType(0)));
+    ResultOps.push_back(NextRecordedOperandNo++);
+    return;
+  }
+  
+  // If this is an explicit register reference, handle it.
+  if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) {
+    if (DI->getDef()->isSubClassOf("Register")) {
+      AddMatcher(new EmitRegisterMatcher(DI->getDef(), N->getType(0)));
+      ResultOps.push_back(NextRecordedOperandNo++);
+      return;
+    }
+    
+    if (DI->getDef()->getName() == "zero_reg") {
+      AddMatcher(new EmitRegisterMatcher(0, N->getType(0)));
+      ResultOps.push_back(NextRecordedOperandNo++);
+      return;
+    }
+    
+    // Handle a reference to a register class. This is used
+    // in COPY_TO_SUBREG instructions.
+    if (DI->getDef()->isSubClassOf("RegisterClass")) {
+      std::string Value = getQualifiedName(DI->getDef()) + "RegClassID";
+      AddMatcher(new EmitStringIntegerMatcher(Value, MVT::i32));
+      ResultOps.push_back(NextRecordedOperandNo++);
+      return;
+    }
+
+    // Handle a subregister index. This is used for INSERT_SUBREG etc.
+    if (DI->getDef()->isSubClassOf("SubRegIndex")) {
+      std::string Value = getQualifiedName(DI->getDef());
+      AddMatcher(new EmitStringIntegerMatcher(Value, MVT::i32));
+      ResultOps.push_back(NextRecordedOperandNo++);
+      return;
+    }
+  }
+  
+  errs() << "unhandled leaf node: \n";
+  N->dump();
+}
+
+/// GetInstPatternNode - Get the pattern for an instruction.
+/// 
+const TreePatternNode *MatcherGen::
+GetInstPatternNode(const DAGInstruction &Inst, const TreePatternNode *N) {
+  const TreePattern *InstPat = Inst.getPattern();
+  
+  // FIXME2?: Assume actual pattern comes before "implicit".
+  TreePatternNode *InstPatNode;
+  if (InstPat)
+    InstPatNode = InstPat->getTree(0);
+  else if (/*isRoot*/ N == Pattern.getDstPattern())
+    InstPatNode = Pattern.getSrcPattern();
+  else
+    return 0;
+  
+  if (InstPatNode && !InstPatNode->isLeaf() &&
+      InstPatNode->getOperator()->getName() == "set")
+    InstPatNode = InstPatNode->getChild(InstPatNode->getNumChildren()-1);
+  
+  return InstPatNode;
+}
+
+void MatcherGen::
+EmitResultInstructionAsOperand(const TreePatternNode *N,
+                               SmallVectorImpl<unsigned> &OutputOps) {
+  Record *Op = N->getOperator();
+  const CodeGenTarget &CGT = CGP.getTargetInfo();
+  CodeGenInstruction &II = CGT.getInstruction(Op);
+  const DAGInstruction &Inst = CGP.getInstruction(Op);
+  
+  // If we can, get the pattern for the instruction we're generating.  We derive
+  // a variety of information from this pattern, such as whether it has a chain.
+  //
+  // FIXME2: This is extremely dubious for several reasons, not the least of
+  // which it gives special status to instructions with patterns that Pat<>
+  // nodes can't duplicate.
+  const TreePatternNode *InstPatNode = GetInstPatternNode(Inst, N);
+
+  // NodeHasChain - Whether the instruction node we're creating takes chains.  
+  bool NodeHasChain = InstPatNode &&
+                      InstPatNode->TreeHasProperty(SDNPHasChain, CGP);
+  
+  bool isRoot = N == Pattern.getDstPattern();
+
+  // TreeHasOutFlag - True if this tree has a flag.
+  bool TreeHasInFlag = false, TreeHasOutFlag = false;
+  if (isRoot) {
+    const TreePatternNode *SrcPat = Pattern.getSrcPattern();
+    TreeHasInFlag = SrcPat->TreeHasProperty(SDNPOptInFlag, CGP) ||
+                    SrcPat->TreeHasProperty(SDNPInFlag, CGP);
+  
+    // FIXME2: this is checking the entire pattern, not just the node in
+    // question, doing this just for the root seems like a total hack.
+    TreeHasOutFlag = SrcPat->TreeHasProperty(SDNPOutFlag, CGP);
+  }
+
+  // NumResults - This is the number of results produced by the instruction in
+  // the "outs" list.
+  unsigned NumResults = Inst.getNumResults();    
+
+  // Loop over all of the operands of the instruction pattern, emitting code
+  // to fill them all in.  The node 'N' usually has number children equal to
+  // the number of input operands of the instruction.  However, in cases
+  // where there are predicate operands for an instruction, we need to fill
+  // in the 'execute always' values.  Match up the node operands to the
+  // instruction operands to do this.
+  SmallVector<unsigned, 8> InstOps;
+  for (unsigned ChildNo = 0, InstOpNo = NumResults, e = II.OperandList.size();
+       InstOpNo != e; ++InstOpNo) {
+    
+    // Determine what to emit for this operand.
+    Record *OperandNode = II.OperandList[InstOpNo].Rec;
+    if ((OperandNode->isSubClassOf("PredicateOperand") ||
+         OperandNode->isSubClassOf("OptionalDefOperand")) &&
+        !CGP.getDefaultOperand(OperandNode).DefaultOps.empty()) {
+      // This is a predicate or optional def operand; emit the
+      // 'default ops' operands.
+      const DAGDefaultOperand &DefaultOp
+	= CGP.getDefaultOperand(OperandNode);
+      for (unsigned i = 0, e = DefaultOp.DefaultOps.size(); i != e; ++i)
+        EmitResultOperand(DefaultOp.DefaultOps[i], InstOps);
+      continue;
+    }
+    
+    const TreePatternNode *Child = N->getChild(ChildNo);
+    
+    // Otherwise this is a normal operand or a predicate operand without
+    // 'execute always'; emit it.
+    unsigned BeforeAddingNumOps = InstOps.size();
+    EmitResultOperand(Child, InstOps);
+    assert(InstOps.size() > BeforeAddingNumOps && "Didn't add any operands");
+    
+    // If the operand is an instruction and it produced multiple results, just
+    // take the first one.
+    if (!Child->isLeaf() && Child->getOperator()->isSubClassOf("Instruction"))
+      InstOps.resize(BeforeAddingNumOps+1);
+    
+    ++ChildNo;
+  }
+  
+  // If this node has an input flag or explicitly specified input physregs, we
+  // need to add chained and flagged copyfromreg nodes and materialize the flag
+  // input.
+  if (isRoot && !PhysRegInputs.empty()) {
+    // Emit all of the CopyToReg nodes for the input physical registers.  These
+    // occur in patterns like (mul:i8 AL:i8, GR8:i8:$src).
+    for (unsigned i = 0, e = PhysRegInputs.size(); i != e; ++i)
+      AddMatcher(new EmitCopyToRegMatcher(PhysRegInputs[i].second,
+                                          PhysRegInputs[i].first));
+    // Even if the node has no other flag inputs, the resultant node must be
+    // flagged to the CopyFromReg nodes we just generated.
+    TreeHasInFlag = true;
+  }
+  
+  // Result order: node results, chain, flags
+  
+  // Determine the result types.
+  SmallVector<MVT::SimpleValueType, 4> ResultVTs;
+  for (unsigned i = 0, e = N->getNumTypes(); i != e; ++i)
+    ResultVTs.push_back(N->getType(i));
+  
+  // If this is the root instruction of a pattern that has physical registers in
+  // its result pattern, add output VTs for them.  For example, X86 has:
+  //   (set AL, (mul ...))
+  // This also handles implicit results like:
+  //   (implicit EFLAGS)
+  if (isRoot && !Pattern.getDstRegs().empty()) {
+    // If the root came from an implicit def in the instruction handling stuff,
+    // don't re-add it.
+    Record *HandledReg = 0;
+    if (II.HasOneImplicitDefWithKnownVT(CGT) != MVT::Other)
+      HandledReg = II.ImplicitDefs[0];
+    
+    for (unsigned i = 0; i != Pattern.getDstRegs().size(); ++i) {
+      Record *Reg = Pattern.getDstRegs()[i];
+      if (!Reg->isSubClassOf("Register") || Reg == HandledReg) continue;
+      ResultVTs.push_back(getRegisterValueType(Reg, CGT));
+    }
+  }
+
+  // If this is the root of the pattern and the pattern we're matching includes
+  // a node that is variadic, mark the generated node as variadic so that it
+  // gets the excess operands from the input DAG.
+  int NumFixedArityOperands = -1;
+  if (isRoot &&
+      (Pattern.getSrcPattern()->NodeHasProperty(SDNPVariadic, CGP)))
+    NumFixedArityOperands = Pattern.getSrcPattern()->getNumChildren();
+  
+  // If this is the root node and any of the nodes matched nodes in the input
+  // pattern have MemRefs in them, have the interpreter collect them and plop
+  // them onto this node.
+  //
+  // FIXME3: This is actively incorrect for result patterns where the root of
+  // the pattern is not the memory reference and is also incorrect when the
+  // result pattern has multiple memory-referencing instructions.  For example,
+  // in the X86 backend, this pattern causes the memrefs to get attached to the
+  // CVTSS2SDrr instead of the MOVSSrm:
+  //
+  //  def : Pat<(extloadf32 addr:$src),
+  //            (CVTSS2SDrr (MOVSSrm addr:$src))>;
+  //
+  bool NodeHasMemRefs =
+    isRoot && Pattern.getSrcPattern()->TreeHasProperty(SDNPMemOperand, CGP);
+
+  assert((!ResultVTs.empty() || TreeHasOutFlag || NodeHasChain) &&
+         "Node has no result");
+  
+  AddMatcher(new EmitNodeMatcher(II.Namespace+"::"+II.TheDef->getName(),
+                                 ResultVTs.data(), ResultVTs.size(),
+                                 InstOps.data(), InstOps.size(),
+                                 NodeHasChain, TreeHasInFlag, TreeHasOutFlag,
+                                 NodeHasMemRefs, NumFixedArityOperands,
+                                 NextRecordedOperandNo));
+  
+  // The non-chain and non-flag results of the newly emitted node get recorded.
+  for (unsigned i = 0, e = ResultVTs.size(); i != e; ++i) {
+    if (ResultVTs[i] == MVT::Other || ResultVTs[i] == MVT::Flag) break;
+    OutputOps.push_back(NextRecordedOperandNo++);
+  }
+}
+
+void MatcherGen::
+EmitResultSDNodeXFormAsOperand(const TreePatternNode *N,
+                               SmallVectorImpl<unsigned> &ResultOps) {
+  assert(N->getOperator()->isSubClassOf("SDNodeXForm") && "Not SDNodeXForm?");
+
+  // Emit the operand.
+  SmallVector<unsigned, 8> InputOps;
+  
+  // FIXME2: Could easily generalize this to support multiple inputs and outputs
+  // to the SDNodeXForm.  For now we just support one input and one output like
+  // the old instruction selector.
+  assert(N->getNumChildren() == 1);
+  EmitResultOperand(N->getChild(0), InputOps);
+
+  // The input currently must have produced exactly one result.
+  assert(InputOps.size() == 1 && "Unexpected input to SDNodeXForm");
+
+  AddMatcher(new EmitNodeXFormMatcher(InputOps[0], N->getOperator()));
+  ResultOps.push_back(NextRecordedOperandNo++);
+}
+
+void MatcherGen::EmitResultOperand(const TreePatternNode *N,
+                                   SmallVectorImpl<unsigned> &ResultOps) {
+  // This is something selected from the pattern we matched.
+  if (!N->getName().empty())
+    return EmitResultOfNamedOperand(N, ResultOps);
+
+  if (N->isLeaf())
+    return EmitResultLeafAsOperand(N, ResultOps);
+
+  Record *OpRec = N->getOperator();
+  if (OpRec->isSubClassOf("Instruction"))
+    return EmitResultInstructionAsOperand(N, ResultOps);
+  if (OpRec->isSubClassOf("SDNodeXForm"))
+    return EmitResultSDNodeXFormAsOperand(N, ResultOps);
+  errs() << "Unknown result node to emit code for: " << *N << '\n';
+  throw std::string("Unknown node in result pattern!");
+}
+
+void MatcherGen::EmitResultCode() {
+  // Patterns that match nodes with (potentially multiple) chain inputs have to
+  // merge them together into a token factor.  This informs the generated code
+  // what all the chained nodes are.
+  if (!MatchedChainNodes.empty())
+    AddMatcher(new EmitMergeInputChainsMatcher
+               (MatchedChainNodes.data(), MatchedChainNodes.size()));
+  
+  // Codegen the root of the result pattern, capturing the resulting values.
+  SmallVector<unsigned, 8> Ops;
+  EmitResultOperand(Pattern.getDstPattern(), Ops);
+
+  // At this point, we have however many values the result pattern produces.
+  // However, the input pattern might not need all of these.  If there are
+  // excess values at the end (such as implicit defs of condition codes etc)
+  // just lop them off.  This doesn't need to worry about flags or chains, just
+  // explicit results.
+  //
+  unsigned NumSrcResults = Pattern.getSrcPattern()->getNumTypes();
+  
+  // If the pattern also has (implicit) results, count them as well.
+  if (!Pattern.getDstRegs().empty()) {
+    // If the root came from an implicit def in the instruction handling stuff,
+    // don't re-add it.
+    Record *HandledReg = 0;
+    const TreePatternNode *DstPat = Pattern.getDstPattern();
+    if (!DstPat->isLeaf() &&DstPat->getOperator()->isSubClassOf("Instruction")){
+      const CodeGenTarget &CGT = CGP.getTargetInfo();
+      CodeGenInstruction &II = CGT.getInstruction(DstPat->getOperator());
+
+      if (II.HasOneImplicitDefWithKnownVT(CGT) != MVT::Other)
+        HandledReg = II.ImplicitDefs[0];
+    }
+    
+    for (unsigned i = 0; i != Pattern.getDstRegs().size(); ++i) {
+      Record *Reg = Pattern.getDstRegs()[i];
+      if (!Reg->isSubClassOf("Register") || Reg == HandledReg) continue;
+      ++NumSrcResults;
+    }
+  }    
+  
+  assert(Ops.size() >= NumSrcResults && "Didn't provide enough results");
+  Ops.resize(NumSrcResults);
+
+  // If the matched pattern covers nodes which define a flag result, emit a node
+  // that tells the matcher about them so that it can update their results.
+  if (!MatchedFlagResultNodes.empty())
+    AddMatcher(new MarkFlagResultsMatcher(MatchedFlagResultNodes.data(),
+                                          MatchedFlagResultNodes.size()));
+  
+  AddMatcher(new CompleteMatchMatcher(Ops.data(), Ops.size(), Pattern));
+}
+
+
+/// ConvertPatternToMatcher - Create the matcher for the specified pattern with
+/// the specified variant.  If the variant number is invalid, this returns null.
+Matcher *llvm::ConvertPatternToMatcher(const PatternToMatch &Pattern,
+                                       unsigned Variant,
+                                       const CodeGenDAGPatterns &CGP) {
+  MatcherGen Gen(Pattern, CGP);
+
+  // Generate the code for the matcher.
+  if (Gen.EmitMatcherCode(Variant))
+    return 0;
+  
+  // FIXME2: Kill extra MoveParent commands at the end of the matcher sequence.
+  // FIXME2: Split result code out to another table, and make the matcher end
+  // with an "Emit <index>" command.  This allows result generation stuff to be
+  // shared and factored?
+  
+  // If the match succeeds, then we generate Pattern.
+  Gen.EmitResultCode();
+
+  // Unconditional match.
+  return Gen.GetMatcher();
+}
diff --git a/src/LLVM/utils/TableGen/DAGISelMatcherOpt.cpp b/src/LLVM/utils/TableGen/DAGISelMatcherOpt.cpp
new file mode 100644
index 0000000..c73bdb9
--- /dev/null
+++ b/src/LLVM/utils/TableGen/DAGISelMatcherOpt.cpp
@@ -0,0 +1,514 @@
+//===- DAGISelMatcherOpt.cpp - Optimize a DAG Matcher ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the DAG Matcher optimizer.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "isel-opt"
+#include "DAGISelMatcher.h"
+#include "CodeGenDAGPatterns.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include <vector>
+using namespace llvm;
+
+/// ContractNodes - Turn multiple matcher node patterns like 'MoveChild+Record'
+/// into single compound nodes like RecordChild.
+static void ContractNodes(OwningPtr<Matcher> &MatcherPtr,
+                          const CodeGenDAGPatterns &CGP) {
+  // If we reached the end of the chain, we're done.
+  Matcher *N = MatcherPtr.get();
+  if (N == 0) return;
+  
+  // If we have a scope node, walk down all of the children.
+  if (ScopeMatcher *Scope = dyn_cast<ScopeMatcher>(N)) {
+    for (unsigned i = 0, e = Scope->getNumChildren(); i != e; ++i) {
+      OwningPtr<Matcher> Child(Scope->takeChild(i));
+      ContractNodes(Child, CGP);
+      Scope->resetChild(i, Child.take());
+    }
+    return;
+  }
+  
+  // If we found a movechild node with a node that comes in a 'foochild' form,
+  // transform it.
+  if (MoveChildMatcher *MC = dyn_cast<MoveChildMatcher>(N)) {
+    Matcher *New = 0;
+    if (RecordMatcher *RM = dyn_cast<RecordMatcher>(MC->getNext()))
+      if (MC->getChildNo() < 8)  // Only have RecordChild0...7
+        New = new RecordChildMatcher(MC->getChildNo(), RM->getWhatFor(),
+                                     RM->getResultNo());
+    
+    if (CheckTypeMatcher *CT = dyn_cast<CheckTypeMatcher>(MC->getNext()))
+      if (MC->getChildNo() < 8 &&  // Only have CheckChildType0...7
+          CT->getResNo() == 0)     // CheckChildType checks res #0
+        New = new CheckChildTypeMatcher(MC->getChildNo(), CT->getType());
+    
+    if (New) {
+      // Insert the new node.
+      New->setNext(MatcherPtr.take());
+      MatcherPtr.reset(New);
+      // Remove the old one.
+      MC->setNext(MC->getNext()->takeNext());
+      return ContractNodes(MatcherPtr, CGP);
+    }
+  }
+  
+  // Zap movechild -> moveparent.
+  if (MoveChildMatcher *MC = dyn_cast<MoveChildMatcher>(N))
+    if (MoveParentMatcher *MP = 
+          dyn_cast<MoveParentMatcher>(MC->getNext())) {
+      MatcherPtr.reset(MP->takeNext());
+      return ContractNodes(MatcherPtr, CGP);
+    }
+
+  // Turn EmitNode->MarkFlagResults->CompleteMatch into
+  // MarkFlagResults->EmitNode->CompleteMatch when we can to encourage
+  // MorphNodeTo formation.  This is safe because MarkFlagResults never refers
+  // to the root of the pattern.
+  if (isa<EmitNodeMatcher>(N) && isa<MarkFlagResultsMatcher>(N->getNext()) &&
+      isa<CompleteMatchMatcher>(N->getNext()->getNext())) {
+    // Unlink the two nodes from the list.
+    Matcher *EmitNode = MatcherPtr.take();
+    Matcher *MFR = EmitNode->takeNext();
+    Matcher *Tail = MFR->takeNext();
+        
+    // Relink them.
+    MatcherPtr.reset(MFR);
+    MFR->setNext(EmitNode);
+    EmitNode->setNext(Tail);
+    return ContractNodes(MatcherPtr, CGP);
+  }
+
+  // Turn EmitNode->CompleteMatch into MorphNodeTo if we can.
+  if (EmitNodeMatcher *EN = dyn_cast<EmitNodeMatcher>(N))
+    if (CompleteMatchMatcher *CM =
+          dyn_cast<CompleteMatchMatcher>(EN->getNext())) {
+      // We can only use MorphNodeTo if the result values match up.
+      unsigned RootResultFirst = EN->getFirstResultSlot();
+      bool ResultsMatch = true;
+      for (unsigned i = 0, e = CM->getNumResults(); i != e; ++i)
+        if (CM->getResult(i) != RootResultFirst+i)
+          ResultsMatch = false;
+      
+      // If the selected node defines a subset of the flag/chain results, we
+      // can't use MorphNodeTo.  For example, we can't use MorphNodeTo if the
+      // matched pattern has a chain but the root node doesn't.
+      const PatternToMatch &Pattern = CM->getPattern();
+      
+      if (!EN->hasChain() &&
+          Pattern.getSrcPattern()->NodeHasProperty(SDNPHasChain, CGP))
+        ResultsMatch = false;
+
+      // If the matched node has a flag and the output root doesn't, we can't
+      // use MorphNodeTo.
+      //
+      // NOTE: Strictly speaking, we don't have to check for the flag here
+      // because the code in the pattern generator doesn't handle it right.  We
+      // do it anyway for thoroughness.
+      if (!EN->hasOutFlag() &&
+          Pattern.getSrcPattern()->NodeHasProperty(SDNPOutFlag, CGP))
+        ResultsMatch = false;
+      
+      
+      // If the root result node defines more results than the source root node
+      // *and* has a chain or flag input, then we can't match it because it
+      // would end up replacing the extra result with the chain/flag.
+#if 0
+      if ((EN->hasFlag() || EN->hasChain()) &&
+          EN->getNumNonChainFlagVTs() > ... need to get no results reliably ...)
+        ResultMatch = false;
+#endif
+          
+      if (ResultsMatch) {
+        const SmallVectorImpl<MVT::SimpleValueType> &VTs = EN->getVTList();
+        const SmallVectorImpl<unsigned> &Operands = EN->getOperandList();
+        MatcherPtr.reset(new MorphNodeToMatcher(EN->getOpcodeName(),
+                                                VTs.data(), VTs.size(),
+                                                Operands.data(),Operands.size(),
+                                                EN->hasChain(), EN->hasInFlag(),
+                                                EN->hasOutFlag(),
+                                                EN->hasMemRefs(),
+                                                EN->getNumFixedArityOperands(),
+                                                Pattern));
+        return;
+      }
+
+      // FIXME2: Kill off all the SelectionDAG::SelectNodeTo and getMachineNode
+      // variants.
+    }
+  
+  ContractNodes(N->getNextPtr(), CGP);
+  
+  
+  // If we have a CheckType/CheckChildType/Record node followed by a
+  // CheckOpcode, invert the two nodes.  We prefer to do structural checks
+  // before type checks, as this opens opportunities for factoring on targets
+  // like X86 where many operations are valid on multiple types.
+  if ((isa<CheckTypeMatcher>(N) || isa<CheckChildTypeMatcher>(N) ||
+       isa<RecordMatcher>(N)) &&
+      isa<CheckOpcodeMatcher>(N->getNext())) {
+    // Unlink the two nodes from the list.
+    Matcher *CheckType = MatcherPtr.take();
+    Matcher *CheckOpcode = CheckType->takeNext();
+    Matcher *Tail = CheckOpcode->takeNext();
+    
+    // Relink them.
+    MatcherPtr.reset(CheckOpcode);
+    CheckOpcode->setNext(CheckType);
+    CheckType->setNext(Tail);
+    return ContractNodes(MatcherPtr, CGP);
+  }
+}
+
+/// SinkPatternPredicates - Pattern predicates can be checked at any level of
+/// the matching tree.  The generator dumps them at the top level of the pattern
+/// though, which prevents factoring from being able to see past them.  This
+/// optimization sinks them as far down into the pattern as possible.
+///
+/// Conceptually, we'd like to sink these predicates all the way to the last
+/// matcher predicate in the series.  However, it turns out that some
+/// ComplexPatterns have side effects on the graph, so we really don't want to
+/// run a the complex pattern if the pattern predicate will fail.  For this
+/// reason, we refuse to sink the pattern predicate past a ComplexPattern.
+///
+static void SinkPatternPredicates(OwningPtr<Matcher> &MatcherPtr) {
+  // Recursively scan for a PatternPredicate.
+  // If we reached the end of the chain, we're done.
+  Matcher *N = MatcherPtr.get();
+  if (N == 0) return;
+  
+  // Walk down all members of a scope node.
+  if (ScopeMatcher *Scope = dyn_cast<ScopeMatcher>(N)) {
+    for (unsigned i = 0, e = Scope->getNumChildren(); i != e; ++i) {
+      OwningPtr<Matcher> Child(Scope->takeChild(i));
+      SinkPatternPredicates(Child);
+      Scope->resetChild(i, Child.take());
+    }
+    return;
+  }
+  
+  // If this node isn't a CheckPatternPredicateMatcher we keep scanning until
+  // we find one.
+  CheckPatternPredicateMatcher *CPPM =dyn_cast<CheckPatternPredicateMatcher>(N);
+  if (CPPM == 0)
+    return SinkPatternPredicates(N->getNextPtr());
+  
+  // Ok, we found one, lets try to sink it. Check if we can sink it past the
+  // next node in the chain.  If not, we won't be able to change anything and
+  // might as well bail.
+  if (!CPPM->getNext()->isSafeToReorderWithPatternPredicate())
+    return;
+  
+  // Okay, we know we can sink it past at least one node.  Unlink it from the
+  // chain and scan for the new insertion point.
+  MatcherPtr.take();  // Don't delete CPPM.
+  MatcherPtr.reset(CPPM->takeNext());
+  
+  N = MatcherPtr.get();
+  while (N->getNext()->isSafeToReorderWithPatternPredicate())
+    N = N->getNext();
+  
+  // At this point, we want to insert CPPM after N.
+  CPPM->setNext(N->takeNext());
+  N->setNext(CPPM);
+}
+
+/// FindNodeWithKind - Scan a series of matchers looking for a matcher with a
+/// specified kind.  Return null if we didn't find one otherwise return the
+/// matcher.
+static Matcher *FindNodeWithKind(Matcher *M, Matcher::KindTy Kind) {
+  for (; M; M = M->getNext())
+    if (M->getKind() == Kind)
+      return M;
+  return 0;
+}
+
+
+/// FactorNodes - Turn matches like this:
+///   Scope
+///     OPC_CheckType i32
+///       ABC
+///     OPC_CheckType i32
+///       XYZ
+/// into:
+///   OPC_CheckType i32
+///     Scope
+///       ABC
+///       XYZ
+///
+static void FactorNodes(OwningPtr<Matcher> &MatcherPtr) {
+  // If we reached the end of the chain, we're done.
+  Matcher *N = MatcherPtr.get();
+  if (N == 0) return;
+  
+  // If this is not a push node, just scan for one.
+  ScopeMatcher *Scope = dyn_cast<ScopeMatcher>(N);
+  if (Scope == 0)
+    return FactorNodes(N->getNextPtr());
+  
+  // Okay, pull together the children of the scope node into a vector so we can
+  // inspect it more easily.  While we're at it, bucket them up by the hash
+  // code of their first predicate.
+  SmallVector<Matcher*, 32> OptionsToMatch;
+  
+  for (unsigned i = 0, e = Scope->getNumChildren(); i != e; ++i) {
+    // Factor the subexpression.
+    OwningPtr<Matcher> Child(Scope->takeChild(i));
+    FactorNodes(Child);
+    
+    if (Matcher *N = Child.take())
+      OptionsToMatch.push_back(N);
+  }
+  
+  SmallVector<Matcher*, 32> NewOptionsToMatch;
+  
+  // Loop over options to match, merging neighboring patterns with identical
+  // starting nodes into a shared matcher.
+  for (unsigned OptionIdx = 0, e = OptionsToMatch.size(); OptionIdx != e;) {
+    // Find the set of matchers that start with this node.
+    Matcher *Optn = OptionsToMatch[OptionIdx++];
+
+    if (OptionIdx == e) {
+      NewOptionsToMatch.push_back(Optn);
+      continue;
+    }
+    
+    // See if the next option starts with the same matcher.  If the two
+    // neighbors *do* start with the same matcher, we can factor the matcher out
+    // of at least these two patterns.  See what the maximal set we can merge
+    // together is.
+    SmallVector<Matcher*, 8> EqualMatchers;
+    EqualMatchers.push_back(Optn);
+    
+    // Factor all of the known-equal matchers after this one into the same
+    // group.
+    while (OptionIdx != e && OptionsToMatch[OptionIdx]->isEqual(Optn))
+      EqualMatchers.push_back(OptionsToMatch[OptionIdx++]);
+
+    // If we found a non-equal matcher, see if it is contradictory with the
+    // current node.  If so, we know that the ordering relation between the
+    // current sets of nodes and this node don't matter.  Look past it to see if
+    // we can merge anything else into this matching group.
+    unsigned Scan = OptionIdx;
+    while (1) {
+      // If we ran out of stuff to scan, we're done.
+      if (Scan == e) break;
+      
+      Matcher *ScanMatcher = OptionsToMatch[Scan];
+      
+      // If we found an entry that matches out matcher, merge it into the set to
+      // handle.
+      if (Optn->isEqual(ScanMatcher)) {
+        // If is equal after all, add the option to EqualMatchers and remove it
+        // from OptionsToMatch.
+        EqualMatchers.push_back(ScanMatcher);
+        OptionsToMatch.erase(OptionsToMatch.begin()+Scan);
+        --e;
+        continue;
+      }
+      
+      // If the option we're checking for contradicts the start of the list,
+      // skip over it.
+      if (Optn->isContradictory(ScanMatcher)) {
+        ++Scan;
+        continue;
+      }
+
+      // If we're scanning for a simple node, see if it occurs later in the
+      // sequence.  If so, and if we can move it up, it might be contradictory
+      // or the same as what we're looking for.  If so, reorder it.
+      if (Optn->isSimplePredicateOrRecordNode()) {
+        Matcher *M2 = FindNodeWithKind(ScanMatcher, Optn->getKind());
+        if (M2 != 0 && M2 != ScanMatcher &&
+            M2->canMoveBefore(ScanMatcher) &&
+            (M2->isEqual(Optn) || M2->isContradictory(Optn))) {
+          Matcher *MatcherWithoutM2 = ScanMatcher->unlinkNode(M2);
+          M2->setNext(MatcherWithoutM2);
+          OptionsToMatch[Scan] = M2;
+          continue;
+        }
+      }
+      
+      // Otherwise, we don't know how to handle this entry, we have to bail.
+      break;
+    }
+      
+    if (Scan != e &&
+        // Don't print it's obvious nothing extra could be merged anyway.
+        Scan+1 != e) {
+      DEBUG(errs() << "Couldn't merge this:\n";
+            Optn->print(errs(), 4);
+            errs() << "into this:\n";
+            OptionsToMatch[Scan]->print(errs(), 4);
+            if (Scan+1 != e)
+              OptionsToMatch[Scan+1]->printOne(errs());
+            if (Scan+2 < e)
+              OptionsToMatch[Scan+2]->printOne(errs());
+            errs() << "\n");
+    }
+    
+    // If we only found one option starting with this matcher, no factoring is
+    // possible.
+    if (EqualMatchers.size() == 1) {
+      NewOptionsToMatch.push_back(EqualMatchers[0]);
+      continue;
+    }
+    
+    // Factor these checks by pulling the first node off each entry and
+    // discarding it.  Take the first one off the first entry to reuse.
+    Matcher *Shared = Optn;
+    Optn = Optn->takeNext();
+    EqualMatchers[0] = Optn;
+
+    // Remove and delete the first node from the other matchers we're factoring.
+    for (unsigned i = 1, e = EqualMatchers.size(); i != e; ++i) {
+      Matcher *Tmp = EqualMatchers[i]->takeNext();
+      delete EqualMatchers[i];
+      EqualMatchers[i] = Tmp;
+    }
+    
+    Shared->setNext(new ScopeMatcher(&EqualMatchers[0], EqualMatchers.size()));
+
+    // Recursively factor the newly created node.
+    FactorNodes(Shared->getNextPtr());
+    
+    NewOptionsToMatch.push_back(Shared);
+  }
+  
+  // If we're down to a single pattern to match, then we don't need this scope
+  // anymore.
+  if (NewOptionsToMatch.size() == 1) {
+    MatcherPtr.reset(NewOptionsToMatch[0]);
+    return;
+  }
+  
+  if (NewOptionsToMatch.empty()) {
+    MatcherPtr.reset(0);
+    return;
+  }
+  
+  // If our factoring failed (didn't achieve anything) see if we can simplify in
+  // other ways.
+  
+  // Check to see if all of the leading entries are now opcode checks.  If so,
+  // we can convert this Scope to be a OpcodeSwitch instead.
+  bool AllOpcodeChecks = true, AllTypeChecks = true;
+  for (unsigned i = 0, e = NewOptionsToMatch.size(); i != e; ++i) {
+    // Check to see if this breaks a series of CheckOpcodeMatchers.
+    if (AllOpcodeChecks &&
+        !isa<CheckOpcodeMatcher>(NewOptionsToMatch[i])) {
+#if 0
+      if (i > 3) {
+        errs() << "FAILING OPC #" << i << "\n";
+        NewOptionsToMatch[i]->dump();
+      }
+#endif
+      AllOpcodeChecks = false;
+    }
+
+    // Check to see if this breaks a series of CheckTypeMatcher's.
+    if (AllTypeChecks) {
+      CheckTypeMatcher *CTM =
+        cast_or_null<CheckTypeMatcher>(FindNodeWithKind(NewOptionsToMatch[i],
+                                                        Matcher::CheckType));
+      if (CTM == 0 ||
+          // iPTR checks could alias any other case without us knowing, don't
+          // bother with them.
+          CTM->getType() == MVT::iPTR ||
+          // SwitchType only works for result #0.
+          CTM->getResNo() != 0 ||
+          // If the CheckType isn't at the start of the list, see if we can move
+          // it there.
+          !CTM->canMoveBefore(NewOptionsToMatch[i])) {
+#if 0
+        if (i > 3 && AllTypeChecks) {
+          errs() << "FAILING TYPE #" << i << "\n";
+          NewOptionsToMatch[i]->dump();
+        }
+#endif
+        AllTypeChecks = false;
+      }
+    }
+  }
+  
+  // If all the options are CheckOpcode's, we can form the SwitchOpcode, woot.
+  if (AllOpcodeChecks) {
+    StringSet<> Opcodes;
+    SmallVector<std::pair<const SDNodeInfo*, Matcher*>, 8> Cases;
+    for (unsigned i = 0, e = NewOptionsToMatch.size(); i != e; ++i) {
+      CheckOpcodeMatcher *COM = cast<CheckOpcodeMatcher>(NewOptionsToMatch[i]);
+      assert(Opcodes.insert(COM->getOpcode().getEnumName()) &&
+             "Duplicate opcodes not factored?");
+      Cases.push_back(std::make_pair(&COM->getOpcode(), COM->getNext()));
+    }
+    
+    MatcherPtr.reset(new SwitchOpcodeMatcher(&Cases[0], Cases.size()));
+    return;
+  }
+  
+  // If all the options are CheckType's, we can form the SwitchType, woot.
+  if (AllTypeChecks) {
+    DenseMap<unsigned, unsigned> TypeEntry;
+    SmallVector<std::pair<MVT::SimpleValueType, Matcher*>, 8> Cases;
+    for (unsigned i = 0, e = NewOptionsToMatch.size(); i != e; ++i) {
+      CheckTypeMatcher *CTM =
+        cast_or_null<CheckTypeMatcher>(FindNodeWithKind(NewOptionsToMatch[i],
+                                                        Matcher::CheckType));
+      Matcher *MatcherWithoutCTM = NewOptionsToMatch[i]->unlinkNode(CTM);
+      MVT::SimpleValueType CTMTy = CTM->getType();
+      delete CTM;
+      
+      unsigned &Entry = TypeEntry[CTMTy];
+      if (Entry != 0) {
+        // If we have unfactored duplicate types, then we should factor them.
+        Matcher *PrevMatcher = Cases[Entry-1].second;
+        if (ScopeMatcher *SM = dyn_cast<ScopeMatcher>(PrevMatcher)) {
+          SM->setNumChildren(SM->getNumChildren()+1);
+          SM->resetChild(SM->getNumChildren()-1, MatcherWithoutCTM);
+          continue;
+        }
+        
+        Matcher *Entries[2] = { PrevMatcher, MatcherWithoutCTM };
+        Cases[Entry-1].second = new ScopeMatcher(Entries, 2);
+        continue;
+      }
+      
+      Entry = Cases.size()+1;
+      Cases.push_back(std::make_pair(CTMTy, MatcherWithoutCTM));
+    }
+    
+    if (Cases.size() != 1) {
+      MatcherPtr.reset(new SwitchTypeMatcher(&Cases[0], Cases.size()));
+    } else {
+      // If we factored and ended up with one case, create it now.
+      MatcherPtr.reset(new CheckTypeMatcher(Cases[0].first, 0));
+      MatcherPtr->setNext(Cases[0].second);
+    }
+    return;
+  }
+  
+
+  // Reassemble the Scope node with the adjusted children.
+  Scope->setNumChildren(NewOptionsToMatch.size());
+  for (unsigned i = 0, e = NewOptionsToMatch.size(); i != e; ++i)
+    Scope->resetChild(i, NewOptionsToMatch[i]);
+}
+
+Matcher *llvm::OptimizeMatcher(Matcher *TheMatcher,
+                               const CodeGenDAGPatterns &CGP) {
+  OwningPtr<Matcher> MatcherPtr(TheMatcher);
+  ContractNodes(MatcherPtr, CGP);
+  SinkPatternPredicates(MatcherPtr);
+  FactorNodes(MatcherPtr);
+  return MatcherPtr.take();
+}
diff --git a/src/LLVM/utils/TableGen/DisassemblerEmitter.cpp b/src/LLVM/utils/TableGen/DisassemblerEmitter.cpp
new file mode 100644
index 0000000..3284366
--- /dev/null
+++ b/src/LLVM/utils/TableGen/DisassemblerEmitter.cpp
@@ -0,0 +1,137 @@
+//===- DisassemblerEmitter.cpp - Generate a disassembler ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DisassemblerEmitter.h"
+#include "CodeGenTarget.h"
+#include "Record.h"
+#include "X86DisassemblerTables.h"
+#include "X86RecognizableInstr.h"
+#include "ARMDecoderEmitter.h"
+
+using namespace llvm;
+using namespace llvm::X86Disassembler;
+
+/// DisassemblerEmitter - Contains disassembler table emitters for various
+/// architectures.
+
+/// X86 Disassembler Emitter
+///
+/// *** IF YOU'RE HERE TO RESOLVE A "Primary decode conflict", LOOK DOWN NEAR
+///     THE END OF THIS COMMENT!
+///
+/// The X86 disassembler emitter is part of the X86 Disassembler, which is
+/// documented in lib/Target/X86/X86Disassembler.h.
+///
+/// The emitter produces the tables that the disassembler uses to translate
+/// instructions.  The emitter generates the following tables:
+///
+/// - One table (CONTEXTS_SYM) that contains a mapping of attribute masks to
+///   instruction contexts.  Although for each attribute there are cases where
+///   that attribute determines decoding, in the majority of cases decoding is
+///   the same whether or not an attribute is present.  For example, a 64-bit
+///   instruction with an OPSIZE prefix and an XS prefix decodes the same way in
+///   all cases as a 64-bit instruction with only OPSIZE set.  (The XS prefix
+///   may have effects on its execution, but does not change the instruction
+///   returned.)  This allows considerable space savings in other tables.
+/// - Four tables (ONEBYTE_SYM, TWOBYTE_SYM, THREEBYTE38_SYM, and
+///   THREEBYTE3A_SYM) contain the hierarchy that the decoder traverses while
+///   decoding an instruction.  At the lowest level of this hierarchy are
+///   instruction UIDs, 16-bit integers that can be used to uniquely identify
+///   the instruction and correspond exactly to its position in the list of
+///   CodeGenInstructions for the target.
+/// - One table (INSTRUCTIONS_SYM) contains information about the operands of
+///   each instruction and how to decode them.
+///
+/// During table generation, there may be conflicts between instructions that
+/// occupy the same space in the decode tables.  These conflicts are resolved as
+/// follows in setTableFields() (X86DisassemblerTables.cpp)
+///
+/// - If the current context is the native context for one of the instructions
+///   (that is, the attributes specified for it in the LLVM tables specify
+///   precisely the current context), then it has priority.
+/// - If the current context isn't native for either of the instructions, then
+///   the higher-priority context wins (that is, the one that is more specific).
+///   That hierarchy is determined by outranks() (X86DisassemblerTables.cpp)
+/// - If the current context is native for both instructions, then the table
+///   emitter reports a conflict and dies.
+///
+/// *** RESOLUTION FOR "Primary decode conflict"S
+///
+/// If two instructions collide, typically the solution is (in order of
+/// likelihood):
+///
+/// (1) to filter out one of the instructions by editing filter()
+///     (X86RecognizableInstr.cpp).  This is the most common resolution, but
+///     check the Intel manuals first to make sure that (2) and (3) are not the
+///     problem.
+/// (2) to fix the tables (X86.td and its subsidiaries) so the opcodes are
+///     accurate.  Sometimes they are not.
+/// (3) to fix the tables to reflect the actual context (for example, required
+///     prefixes), and possibly to add a new context by editing
+///     lib/Target/X86/X86DisassemblerDecoderCommon.h.  This is unlikely to be
+///     the cause.
+///
+/// DisassemblerEmitter.cpp contains the implementation for the emitter,
+///   which simply pulls out instructions from the CodeGenTarget and pushes them
+///   into X86DisassemblerTables.
+/// X86DisassemblerTables.h contains the interface for the instruction tables,
+///   which manage and emit the structures discussed above.
+/// X86DisassemblerTables.cpp contains the implementation for the instruction
+///   tables.
+/// X86ModRMFilters.h contains filters that can be used to determine which
+///   ModR/M values are valid for a particular instruction.  These are used to
+///   populate ModRMDecisions.
+/// X86RecognizableInstr.h contains the interface for a single instruction,
+///   which knows how to translate itself from a CodeGenInstruction and provide
+///   the information necessary for integration into the tables.
+/// X86RecognizableInstr.cpp contains the implementation for a single
+///   instruction.
+
+void DisassemblerEmitter::run(raw_ostream &OS) {
+  CodeGenTarget Target;
+
+  OS << "/*===- TableGen'erated file "
+     << "---------------------------------------*- C -*-===*\n"
+     << " *\n"
+     << " * " << Target.getName() << " Disassembler\n"
+     << " *\n"
+     << " * Automatically generated file, do not edit!\n"
+     << " *\n"
+     << " *===---------------------------------------------------------------"
+     << "-------===*/\n";
+
+  // X86 uses a custom disassembler.
+  if (Target.getName() == "X86") {
+    DisassemblerTables Tables;
+  
+    const std::vector<const CodeGenInstruction*> &numberedInstructions =
+      Target.getInstructionsByEnumValue();
+    
+    for (unsigned i = 0, e = numberedInstructions.size(); i != e; ++i)
+      RecognizableInstr::processInstr(Tables, *numberedInstructions[i], i);
+
+    // FIXME: As long as we are using exceptions, might as well drop this to the
+    // actual conflict site.
+    if (Tables.hasConflicts())
+      throw TGError(Target.getTargetRecord()->getLoc(),
+                    "Primary decode conflict");
+
+    Tables.emit(OS);
+    return;
+  }
+
+  // Fixed-instruction-length targets use a common disassembler.
+  if (Target.getName() == "ARM") {
+    ARMDecoderEmitter(Records).run(OS);
+    return;
+  }  
+
+  throw TGError(Target.getTargetRecord()->getLoc(),
+                "Unable to generate disassembler for this target");
+}
diff --git a/src/LLVM/utils/TableGen/DisassemblerEmitter.h b/src/LLVM/utils/TableGen/DisassemblerEmitter.h
new file mode 100644
index 0000000..7229d81
--- /dev/null
+++ b/src/LLVM/utils/TableGen/DisassemblerEmitter.h
@@ -0,0 +1,28 @@
+//===- DisassemblerEmitter.h - Disassembler Generator -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef DISASSEMBLEREMITTER_H
+#define DISASSEMBLEREMITTER_H
+
+#include "TableGenBackend.h"
+
+namespace llvm {
+
+  class DisassemblerEmitter : public TableGenBackend {
+    RecordKeeper &Records;
+  public:
+    DisassemblerEmitter(RecordKeeper &R) : Records(R) {}
+
+    /// run - Output the disassembler.
+    void run(raw_ostream &o);
+  };
+
+} // end llvm namespace
+
+#endif
diff --git a/src/LLVM/utils/TableGen/EDEmitter.cpp b/src/LLVM/utils/TableGen/EDEmitter.cpp
new file mode 100644
index 0000000..50ff9ea
--- /dev/null
+++ b/src/LLVM/utils/TableGen/EDEmitter.cpp
@@ -0,0 +1,899 @@
+//===- EDEmitter.cpp - Generate instruction descriptions for ED -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend is responsible for emitting a description of each
+// instruction in a format that the enhanced disassembler can use to tokenize
+// and parse instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "EDEmitter.h"
+
+#include "AsmWriterInst.h"
+#include "CodeGenTarget.h"
+#include "Record.h"
+
+#include "llvm/MC/EDInstInfo.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+using namespace llvm;
+
+///////////////////////////////////////////////////////////
+// Support classes for emitting nested C data structures //
+///////////////////////////////////////////////////////////
+
+namespace {
+  
+  class EnumEmitter {
+  private:
+    std::string Name;
+    std::vector<std::string> Entries;
+  public:
+    EnumEmitter(const char *N) : Name(N) { 
+    }
+    int addEntry(const char *e) { 
+      Entries.push_back(std::string(e));
+      return Entries.size() - 1; 
+    }
+    void emit(raw_ostream &o, unsigned int &i) {
+      o.indent(i) << "enum " << Name.c_str() << " {" << "\n";
+      i += 2;
+      
+      unsigned int index = 0;
+      unsigned int numEntries = Entries.size();
+      for (index = 0; index < numEntries; ++index) {
+        o.indent(i) << Entries[index];
+        if (index < (numEntries - 1))
+          o << ",";
+        o << "\n";
+      }
+      
+      i -= 2;
+      o.indent(i) << "};" << "\n";
+    }
+    
+    void emitAsFlags(raw_ostream &o, unsigned int &i) {
+      o.indent(i) << "enum " << Name.c_str() << " {" << "\n";
+      i += 2;
+      
+      unsigned int index = 0;
+      unsigned int numEntries = Entries.size();
+      unsigned int flag = 1;
+      for (index = 0; index < numEntries; ++index) {
+        o.indent(i) << Entries[index] << " = " << format("0x%x", flag);
+        if (index < (numEntries - 1))
+          o << ",";
+        o << "\n";
+        flag <<= 1;
+      }
+      
+      i -= 2;
+      o.indent(i) << "};" << "\n";
+    }
+  };
+
+  class StructEmitter {
+  private:
+    std::string Name;
+    typedef std::pair<const char*, const char*> member;
+    std::vector< member > Members;
+  public:
+    StructEmitter(const char *N) : Name(N) {
+    }
+    void addMember(const char *t, const char *n) {
+      member m(t, n);
+      Members.push_back(m);
+    }
+    void emit(raw_ostream &o, unsigned int &i) {
+      o.indent(i) << "struct " << Name.c_str() << " {" << "\n";
+      i += 2;
+      
+      unsigned int index = 0;
+      unsigned int numMembers = Members.size();
+      for (index = 0; index < numMembers; ++index) {
+        o.indent(i) << Members[index].first << " ";
+        o.indent(i) << Members[index].second << ";" << "\n";
+      }
+      
+      i -= 2;
+      o.indent(i) << "};" << "\n";
+    }
+  };
+  
+  class ConstantEmitter {
+  public:
+    virtual ~ConstantEmitter() { }
+    virtual void emit(raw_ostream &o, unsigned int &i) = 0;
+  };
+  
+  class LiteralConstantEmitter : public ConstantEmitter {
+  private:
+    bool IsNumber;
+    union {
+      int Number;
+      const char* String;
+    };
+  public:
+    LiteralConstantEmitter(const char *string) : 
+      IsNumber(false),
+      String(string) {
+    }
+    LiteralConstantEmitter(int number = 0) : 
+      IsNumber(true),
+      Number(number) {
+    }
+    void set(const char *string) {
+      IsNumber = false;
+      Number = 0;
+      String = string;
+    }
+    void set(int number) {
+      IsNumber = true;
+      String = NULL;
+      Number = number;
+    }
+    bool is(const char *string) {
+      return !strcmp(String, string);
+    }
+    void emit(raw_ostream &o, unsigned int &i) {
+      if (IsNumber)
+        o << Number;
+      else
+        o << String;
+    }
+  };
+  
+  class CompoundConstantEmitter : public ConstantEmitter {
+  private:
+    unsigned int Padding;
+    std::vector<ConstantEmitter *> Entries;
+  public:
+    CompoundConstantEmitter(unsigned int padding = 0) : Padding(padding) {
+    }
+    CompoundConstantEmitter &addEntry(ConstantEmitter *e) {
+      Entries.push_back(e);
+      
+      return *this;
+    }
+    ~CompoundConstantEmitter() {
+      while (Entries.size()) {
+        ConstantEmitter *entry = Entries.back();
+        Entries.pop_back();
+        delete entry;
+      }
+    }
+    void emit(raw_ostream &o, unsigned int &i) {
+      o << "{" << "\n";
+      i += 2;
+  
+      unsigned int index;
+      unsigned int numEntries = Entries.size();
+      
+      unsigned int numToPrint;
+      
+      if (Padding) {
+        if (numEntries > Padding) {
+          fprintf(stderr, "%u entries but %u padding\n", numEntries, Padding);
+          llvm_unreachable("More entries than padding");
+        }
+        numToPrint = Padding;
+      } else {
+        numToPrint = numEntries;
+      }
+          
+      for (index = 0; index < numToPrint; ++index) {
+        o.indent(i);
+        if (index < numEntries)
+          Entries[index]->emit(o, i);
+        else
+          o << "-1";
+        
+        if (index < (numToPrint - 1))
+          o << ",";
+        o << "\n";
+      }
+      
+      i -= 2;
+      o.indent(i) << "}";
+    }
+  };
+  
+  class FlagsConstantEmitter : public ConstantEmitter {
+  private:
+    std::vector<std::string> Flags;
+  public:
+    FlagsConstantEmitter() {
+    }
+    FlagsConstantEmitter &addEntry(const char *f) {
+      Flags.push_back(std::string(f));
+      return *this;
+    }
+    void emit(raw_ostream &o, unsigned int &i) {
+      unsigned int index;
+      unsigned int numFlags = Flags.size();
+      if (numFlags == 0)
+        o << "0";
+      
+      for (index = 0; index < numFlags; ++index) {
+        o << Flags[index].c_str();
+        if (index < (numFlags - 1))
+          o << " | ";
+      }
+    }
+  };
+}
+
+EDEmitter::EDEmitter(RecordKeeper &R) : Records(R) {
+}
+
+/// populateOperandOrder - Accepts a CodeGenInstruction and generates its
+///   AsmWriterInst for the desired assembly syntax, giving an ordered list of
+///   operands in the order they appear in the printed instruction.  Then, for
+///   each entry in that list, determines the index of the same operand in the
+///   CodeGenInstruction, and emits the resulting mapping into an array, filling
+///   in unused slots with -1.
+///
+/// @arg operandOrder - The array that will be populated with the operand
+///                     mapping.  Each entry will contain -1 (invalid index
+///                     into the operands present in the AsmString) or a number
+///                     representing an index in the operand descriptor array.
+/// @arg inst         - The instruction to use when looking up the operands
+/// @arg syntax       - The syntax to use, according to LLVM's enumeration
+void populateOperandOrder(CompoundConstantEmitter *operandOrder,
+                          const CodeGenInstruction &inst,
+                          unsigned syntax) {
+  unsigned int numArgs = 0;
+  
+  AsmWriterInst awInst(inst, syntax, -1, -1);
+  
+  std::vector<AsmWriterOperand>::iterator operandIterator;
+  
+  for (operandIterator = awInst.Operands.begin();
+       operandIterator != awInst.Operands.end();
+       ++operandIterator) {
+    if (operandIterator->OperandType == 
+        AsmWriterOperand::isMachineInstrOperand) {
+      operandOrder->addEntry(
+        new LiteralConstantEmitter(operandIterator->CGIOpNo));
+      numArgs++;
+    }
+  }
+}
+
+/////////////////////////////////////////////////////
+// Support functions for handling X86 instructions //
+/////////////////////////////////////////////////////
+
+#define SET(flag) { type->set(flag); return 0; }
+
+#define REG(str) if (name == str) SET("kOperandTypeRegister");
+#define MEM(str) if (name == str) SET("kOperandTypeX86Memory");
+#define LEA(str) if (name == str) SET("kOperandTypeX86EffectiveAddress");
+#define IMM(str) if (name == str) SET("kOperandTypeImmediate");
+#define PCR(str) if (name == str) SET("kOperandTypeX86PCRelative");
+
+/// X86TypeFromOpName - Processes the name of a single X86 operand (which is
+///   actually its type) and translates it into an operand type
+///
+/// @arg flags    - The type object to set
+/// @arg name     - The name of the operand
+static int X86TypeFromOpName(LiteralConstantEmitter *type,
+                             const std::string &name) {
+  REG("GR8");
+  REG("GR8_NOREX");
+  REG("GR16");
+  REG("GR32");
+  REG("GR32_NOREX");
+  REG("GR32_TC");
+  REG("FR32");
+  REG("RFP32");
+  REG("GR64");
+  REG("GR64_TC");
+  REG("FR64");
+  REG("VR64");
+  REG("RFP64");
+  REG("RFP80");
+  REG("VR128");
+  REG("VR256");
+  REG("RST");
+  REG("SEGMENT_REG");
+  REG("DEBUG_REG");
+  REG("CONTROL_REG");
+  
+  IMM("i8imm");
+  IMM("i16imm");
+  IMM("i16i8imm");
+  IMM("i32imm");
+  IMM("i32i8imm");
+  IMM("i64imm");
+  IMM("i64i8imm");
+  IMM("i64i32imm");
+  IMM("SSECC");
+  
+  // all R, I, R, I, R
+  MEM("i8mem");
+  MEM("i8mem_NOREX");
+  MEM("i16mem");
+  MEM("i32mem");
+  MEM("i32mem_TC");
+  MEM("f32mem");
+  MEM("ssmem");
+  MEM("opaque32mem");
+  MEM("opaque48mem");
+  MEM("i64mem");
+  MEM("i64mem_TC");
+  MEM("f64mem");
+  MEM("sdmem");
+  MEM("f80mem");
+  MEM("opaque80mem");
+  MEM("i128mem");
+  MEM("i256mem");
+  MEM("f128mem");
+  MEM("f256mem");
+  MEM("opaque512mem");
+  
+  // all R, I, R, I
+  LEA("lea32mem");
+  LEA("lea64_32mem");
+  LEA("lea64mem");
+  
+  // all I
+  PCR("i16imm_pcrel");
+  PCR("i32imm_pcrel");
+  PCR("i64i32imm_pcrel");
+  PCR("brtarget8");
+  PCR("offset8");
+  PCR("offset16");
+  PCR("offset32");
+  PCR("offset64");
+  PCR("brtarget");
+  
+  return 1;
+}
+
+#undef REG
+#undef MEM
+#undef LEA
+#undef IMM
+#undef PCR
+
+#undef SET
+
+/// X86PopulateOperands - Handles all the operands in an X86 instruction, adding
+///   the appropriate flags to their descriptors
+///
+/// @operandFlags - A reference the array of operand flag objects
+/// @inst         - The instruction to use as a source of information
+static void X86PopulateOperands(
+  LiteralConstantEmitter *(&operandTypes)[EDIS_MAX_OPERANDS],
+  const CodeGenInstruction &inst) {
+  if (!inst.TheDef->isSubClassOf("X86Inst"))
+    return;
+  
+  unsigned int index;
+  unsigned int numOperands = inst.OperandList.size();
+  
+  for (index = 0; index < numOperands; ++index) {
+    const CodeGenInstruction::OperandInfo &operandInfo = 
+      inst.OperandList[index];
+    Record &rec = *operandInfo.Rec;
+    
+    if (X86TypeFromOpName(operandTypes[index], rec.getName())) {
+      errs() << "Operand type: " << rec.getName().c_str() << "\n";
+      errs() << "Operand name: " << operandInfo.Name.c_str() << "\n";
+      errs() << "Instruction mame: " << inst.TheDef->getName().c_str() << "\n";
+      llvm_unreachable("Unhandled type");
+    }
+  }
+}
+
+/// decorate1 - Decorates a named operand with a new flag
+///
+/// @operandFlags - The array of operand flag objects, which don't have names
+/// @inst         - The CodeGenInstruction, which provides a way to translate
+///                 between names and operand indices
+/// @opName       - The name of the operand
+/// @flag         - The name of the flag to add
+static inline void decorate1(
+  FlagsConstantEmitter *(&operandFlags)[EDIS_MAX_OPERANDS],
+  const CodeGenInstruction &inst,
+  const char *opName,
+  const char *opFlag) {
+  unsigned opIndex;
+  
+  opIndex = inst.getOperandNamed(std::string(opName));
+  
+  operandFlags[opIndex]->addEntry(opFlag);
+}
+
+#define DECORATE1(opName, opFlag) decorate1(operandFlags, inst, opName, opFlag)
+
+#define MOV(source, target) {               \
+  instType.set("kInstructionTypeMove");     \
+  DECORATE1(source, "kOperandFlagSource");  \
+  DECORATE1(target, "kOperandFlagTarget");  \
+}
+
+#define BRANCH(target) {                    \
+  instType.set("kInstructionTypeBranch");   \
+  DECORATE1(target, "kOperandFlagTarget");  \
+}
+
+#define PUSH(source) {                      \
+  instType.set("kInstructionTypePush");     \
+  DECORATE1(source, "kOperandFlagSource");  \
+}
+
+#define POP(target) {                       \
+  instType.set("kInstructionTypePop");      \
+  DECORATE1(target, "kOperandFlagTarget");  \
+}
+
+#define CALL(target) {                      \
+  instType.set("kInstructionTypeCall");     \
+  DECORATE1(target, "kOperandFlagTarget");  \
+}
+
+#define RETURN() {                          \
+  instType.set("kInstructionTypeReturn");   \
+}
+
+/// X86ExtractSemantics - Performs various checks on the name of an X86
+///   instruction to determine what sort of an instruction it is and then adds 
+///   the appropriate flags to the instruction and its operands
+///
+/// @arg instType     - A reference to the type for the instruction as a whole
+/// @arg operandFlags - A reference to the array of operand flag object pointers
+/// @arg inst         - A reference to the original instruction
+static void X86ExtractSemantics(
+  LiteralConstantEmitter &instType,
+  FlagsConstantEmitter *(&operandFlags)[EDIS_MAX_OPERANDS],
+  const CodeGenInstruction &inst) {
+  const std::string &name = inst.TheDef->getName();
+    
+  if (name.find("MOV") != name.npos) {
+    if (name.find("MOV_V") != name.npos) {
+      // ignore (this is a pseudoinstruction)
+    } else if (name.find("MASK") != name.npos) {
+      // ignore (this is a masking move)
+    } else if (name.find("r0") != name.npos) {
+      // ignore (this is a pseudoinstruction)
+    } else if (name.find("PS") != name.npos ||
+             name.find("PD") != name.npos) {
+      // ignore (this is a shuffling move)
+    } else if (name.find("MOVS") != name.npos) {
+      // ignore (this is a string move)
+    } else if (name.find("_F") != name.npos) {
+      // TODO handle _F moves to ST(0)
+    } else if (name.find("a") != name.npos) {
+      // TODO handle moves to/from %ax
+    } else if (name.find("CMOV") != name.npos) {
+      MOV("src2", "dst");
+    } else if (name.find("PC") != name.npos) {
+      MOV("label", "reg")
+    } else {
+      MOV("src", "dst");
+    }
+  }
+  
+  if (name.find("JMP") != name.npos ||
+      name.find("J") == 0) {
+    if (name.find("FAR") != name.npos && name.find("i") != name.npos) {
+      BRANCH("off");
+    } else {
+      BRANCH("dst");
+    }
+  }
+  
+  if (name.find("PUSH") != name.npos) {
+    if (name.find("FS") != name.npos ||
+        name.find("GS") != name.npos) {
+      instType.set("kInstructionTypePush");
+      // TODO add support for fixed operands
+    } else if (name.find("F") != name.npos) {
+      // ignore (this pushes onto the FP stack)
+    } else if (name.find("A") != name.npos) {
+      // ignore (pushes all GP registoers onto the stack)
+    } else if (name[name.length() - 1] == 'm') {
+      PUSH("src");
+    } else if (name.find("i") != name.npos) {
+      PUSH("imm");
+    } else {
+      PUSH("reg");
+    }
+  }
+  
+  if (name.find("POP") != name.npos) {
+    if (name.find("POPCNT") != name.npos) {
+      // ignore (not a real pop)
+    } else if (name.find("FS") != name.npos ||
+             name.find("GS") != name.npos) {
+      instType.set("kInstructionTypePop");
+      // TODO add support for fixed operands
+    } else if (name.find("F") != name.npos) {
+      // ignore (this pops from the FP stack)
+    } else if (name.find("A") != name.npos) {
+      // ignore (pushes all GP registoers onto the stack)
+    } else if (name[name.length() - 1] == 'm') {
+      POP("dst");
+    } else {
+      POP("reg");
+    }
+  }
+  
+  if (name.find("CALL") != name.npos) {
+    if (name.find("ADJ") != name.npos) {
+      // ignore (not a call)
+    } else if (name.find("SYSCALL") != name.npos) {
+      // ignore (doesn't go anywhere we know about)
+    } else if (name.find("VMCALL") != name.npos) {
+      // ignore (rather different semantics than a regular call)
+    } else if (name.find("FAR") != name.npos && name.find("i") != name.npos) {
+      CALL("off");
+    } else {
+      CALL("dst");
+    }
+  }
+  
+  if (name.find("RET") != name.npos) {
+    RETURN();
+  }
+}
+
+#undef MOV
+#undef BRANCH
+#undef PUSH
+#undef POP
+#undef CALL
+#undef RETURN
+
+/////////////////////////////////////////////////////
+// Support functions for handling ARM instructions //
+/////////////////////////////////////////////////////
+
+#define SET(flag) { type->set(flag); return 0; }
+
+#define REG(str)    if (name == str) SET("kOperandTypeRegister");
+#define IMM(str)    if (name == str) SET("kOperandTypeImmediate");
+
+#define MISC(str, type)   if (name == str) SET(type);
+
+/// ARMFlagFromOpName - Processes the name of a single ARM operand (which is
+///   actually its type) and translates it into an operand type
+///
+/// @arg type     - The type object to set
+/// @arg name     - The name of the operand
+static int ARMFlagFromOpName(LiteralConstantEmitter *type,
+                             const std::string &name) {
+  REG("GPR");
+  REG("rGPR");
+  REG("tcGPR");
+  REG("cc_out");
+  REG("s_cc_out");
+  REG("tGPR");
+  REG("DPR");
+  REG("DPR_VFP2");
+  REG("DPR_8");
+  REG("SPR");
+  REG("QPR");
+  REG("QQPR");
+  REG("QQQQPR");
+  
+  IMM("i32imm");
+  IMM("bf_inv_mask_imm");
+  IMM("jtblock_operand");
+  IMM("nohash_imm");
+  IMM("cpinst_operand");
+  IMM("cps_opt");
+  IMM("vfp_f64imm");
+  IMM("vfp_f32imm");
+  IMM("msr_mask");
+  IMM("neg_zero");
+  IMM("imm0_31");
+  IMM("nModImm");
+  IMM("imm0_4095");
+  IMM("jt2block_operand");
+  IMM("t_imm_s4");
+  IMM("pclabel");
+  
+  MISC("brtarget", "kOperandTypeARMBranchTarget");                // ?
+  MISC("so_reg", "kOperandTypeARMSoReg");                         // R, R, I
+  MISC("t2_so_reg", "kOperandTypeThumb2SoReg");                   // R, I
+  MISC("so_imm", "kOperandTypeARMSoImm");                         // I
+  MISC("t2_so_imm", "kOperandTypeThumb2SoImm");                   // I
+  MISC("so_imm2part", "kOperandTypeARMSoImm2Part");               // I
+  MISC("pred", "kOperandTypeARMPredicate");                       // I, R
+  MISC("it_pred", "kOperandTypeARMPredicate");                    // I
+  MISC("addrmode2", "kOperandTypeARMAddrMode2");                  // R, R, I
+  MISC("am2offset", "kOperandTypeARMAddrMode2Offset");            // R, I
+  MISC("addrmode3", "kOperandTypeARMAddrMode3");                  // R, R, I
+  MISC("am3offset", "kOperandTypeARMAddrMode3Offset");            // R, I
+  MISC("addrmode4", "kOperandTypeARMAddrMode4");                  // R, I
+  MISC("addrmode5", "kOperandTypeARMAddrMode5");                  // R, I
+  MISC("addrmode6", "kOperandTypeARMAddrMode6");                  // R, R, I, I
+  MISC("am6offset", "kOperandTypeARMAddrMode6Offset");            // R, I, I
+  MISC("addrmodepc", "kOperandTypeARMAddrModePC");                // R, I
+  MISC("reglist", "kOperandTypeARMRegisterList");                 // I, R, ...
+  MISC("it_mask", "kOperandTypeThumbITMask");                     // I
+  MISC("t2addrmode_imm8", "kOperandTypeThumb2AddrModeImm8");      // R, I
+  MISC("t2am_imm8_offset", "kOperandTypeThumb2AddrModeImm8Offset");//I
+  MISC("t2addrmode_imm12", "kOperandTypeThumb2AddrModeImm12");    // R, I
+  MISC("t2addrmode_so_reg", "kOperandTypeThumb2AddrModeSoReg");   // R, R, I
+  MISC("t2addrmode_imm8s4", "kOperandTypeThumb2AddrModeImm8s4");  // R, I
+  MISC("t2am_imm8s4_offset", "kOperandTypeThumb2AddrModeImm8s4Offset");  
+                                                                  // R, I
+  MISC("tb_addrmode", "kOperandTypeARMTBAddrMode");               // I
+  MISC("t_addrmode_s1", "kOperandTypeThumbAddrModeS1");           // R, I, R
+  MISC("t_addrmode_s2", "kOperandTypeThumbAddrModeS2");           // R, I, R
+  MISC("t_addrmode_s4", "kOperandTypeThumbAddrModeS4");           // R, I, R
+  MISC("t_addrmode_rr", "kOperandTypeThumbAddrModeRR");           // R, R
+  MISC("t_addrmode_sp", "kOperandTypeThumbAddrModeSP");           // R, I
+  
+  return 1;
+}
+
+#undef SOREG
+#undef SOIMM
+#undef PRED
+#undef REG
+#undef MEM
+#undef LEA
+#undef IMM
+#undef PCR
+
+#undef SET
+
+/// ARMPopulateOperands - Handles all the operands in an ARM instruction, adding
+///   the appropriate flags to their descriptors
+///
+/// @operandFlags - A reference the array of operand flag objects
+/// @inst         - The instruction to use as a source of information
+static void ARMPopulateOperands(
+  LiteralConstantEmitter *(&operandTypes)[EDIS_MAX_OPERANDS],
+  const CodeGenInstruction &inst) {
+  if (!inst.TheDef->isSubClassOf("InstARM") &&
+      !inst.TheDef->isSubClassOf("InstThumb"))
+    return;
+  
+  unsigned int index;
+  unsigned int numOperands = inst.OperandList.size();
+  
+  if (numOperands > EDIS_MAX_OPERANDS) {
+    errs() << "numOperands == " << numOperands << " > " << 
+      EDIS_MAX_OPERANDS << '\n';
+    llvm_unreachable("Too many operands");
+  }
+  
+  for (index = 0; index < numOperands; ++index) {
+    const CodeGenInstruction::OperandInfo &operandInfo = 
+    inst.OperandList[index];
+    Record &rec = *operandInfo.Rec;
+    
+    if (ARMFlagFromOpName(operandTypes[index], rec.getName())) {
+      errs() << "Operand type: " << rec.getName() << '\n';
+      errs() << "Operand name: " << operandInfo.Name << '\n';
+      errs() << "Instruction mame: " << inst.TheDef->getName() << '\n';
+      llvm_unreachable("Unhandled type");
+    }
+  }
+}
+
+#define BRANCH(target) {                    \
+  instType.set("kInstructionTypeBranch");   \
+  DECORATE1(target, "kOperandFlagTarget");  \
+}
+
+/// ARMExtractSemantics - Performs various checks on the name of an ARM
+///   instruction to determine what sort of an instruction it is and then adds 
+///   the appropriate flags to the instruction and its operands
+///
+/// @arg instType     - A reference to the type for the instruction as a whole
+/// @arg operandTypes - A reference to the array of operand type object pointers
+/// @arg operandFlags - A reference to the array of operand flag object pointers
+/// @arg inst         - A reference to the original instruction
+static void ARMExtractSemantics(
+  LiteralConstantEmitter &instType,
+  LiteralConstantEmitter *(&operandTypes)[EDIS_MAX_OPERANDS],
+  FlagsConstantEmitter *(&operandFlags)[EDIS_MAX_OPERANDS],
+  const CodeGenInstruction &inst) {
+  const std::string &name = inst.TheDef->getName();
+  
+  if (name == "tBcc"   ||
+      name == "tB"     ||
+      name == "t2Bcc"  ||
+      name == "Bcc"    ||
+      name == "tCBZ"   ||
+      name == "tCBNZ") {
+    BRANCH("target");
+  }
+  
+  if (name == "tBLr9"      ||
+      name == "BLr9_pred"  ||
+      name == "tBLXi_r9"   ||
+      name == "tBLXr_r9"   ||
+      name == "BLXr9"      ||
+      name == "t2BXJ"      ||
+      name == "BXJ") {
+    BRANCH("func");
+    
+    unsigned opIndex;
+    opIndex = inst.getOperandNamed("func");
+    if (operandTypes[opIndex]->is("kOperandTypeImmediate"))
+      operandTypes[opIndex]->set("kOperandTypeARMBranchTarget");
+  }
+}
+
+#undef BRANCH
+
+/// populateInstInfo - Fills an array of InstInfos with information about each 
+///   instruction in a target
+///
+/// @arg infoArray  - The array of InstInfo objects to populate
+/// @arg target     - The CodeGenTarget to use as a source of instructions
+static void populateInstInfo(CompoundConstantEmitter &infoArray,
+                             CodeGenTarget &target) {
+  const std::vector<const CodeGenInstruction*> &numberedInstructions =
+    target.getInstructionsByEnumValue();
+  
+  unsigned int index;
+  unsigned int numInstructions = numberedInstructions.size();
+  
+  for (index = 0; index < numInstructions; ++index) {
+    const CodeGenInstruction& inst = *numberedInstructions[index];
+    
+    CompoundConstantEmitter *infoStruct = new CompoundConstantEmitter;
+    infoArray.addEntry(infoStruct);
+    
+    LiteralConstantEmitter *instType = new LiteralConstantEmitter;
+    infoStruct->addEntry(instType);
+    
+    LiteralConstantEmitter *numOperandsEmitter = 
+      new LiteralConstantEmitter(inst.OperandList.size());
+    infoStruct->addEntry(numOperandsEmitter);
+    
+    CompoundConstantEmitter *operandTypeArray = new CompoundConstantEmitter;
+    infoStruct->addEntry(operandTypeArray);
+    
+    LiteralConstantEmitter *operandTypes[EDIS_MAX_OPERANDS];
+                         
+    CompoundConstantEmitter *operandFlagArray = new CompoundConstantEmitter;
+    infoStruct->addEntry(operandFlagArray);
+        
+    FlagsConstantEmitter *operandFlags[EDIS_MAX_OPERANDS];
+    
+    for (unsigned operandIndex = 0; 
+         operandIndex < EDIS_MAX_OPERANDS; 
+         ++operandIndex) {
+      operandTypes[operandIndex] = new LiteralConstantEmitter;
+      operandTypeArray->addEntry(operandTypes[operandIndex]);
+      
+      operandFlags[operandIndex] = new FlagsConstantEmitter;
+      operandFlagArray->addEntry(operandFlags[operandIndex]);
+    }
+ 
+    unsigned numSyntaxes = 0;
+    
+    if (target.getName() == "X86") {
+      X86PopulateOperands(operandTypes, inst);
+      X86ExtractSemantics(*instType, operandFlags, inst);
+      numSyntaxes = 2;
+    }
+    else if (target.getName() == "ARM") {
+      ARMPopulateOperands(operandTypes, inst);
+      ARMExtractSemantics(*instType, operandTypes, operandFlags, inst);
+      numSyntaxes = 1;
+    }
+    
+    CompoundConstantEmitter *operandOrderArray = new CompoundConstantEmitter;    
+    
+    infoStruct->addEntry(operandOrderArray);
+    
+    for (unsigned syntaxIndex = 0; 
+         syntaxIndex < EDIS_MAX_SYNTAXES; 
+         ++syntaxIndex) {
+      CompoundConstantEmitter *operandOrder = 
+        new CompoundConstantEmitter(EDIS_MAX_OPERANDS);
+      
+      operandOrderArray->addEntry(operandOrder);
+      
+      if (syntaxIndex < numSyntaxes) {
+        populateOperandOrder(operandOrder, inst, syntaxIndex);
+      }
+    }
+    
+    infoStruct = NULL;
+  }
+}
+
+static void emitCommonEnums(raw_ostream &o, unsigned int &i) {
+  EnumEmitter operandTypes("OperandTypes");
+  operandTypes.addEntry("kOperandTypeNone");
+  operandTypes.addEntry("kOperandTypeImmediate");
+  operandTypes.addEntry("kOperandTypeRegister");
+  operandTypes.addEntry("kOperandTypeX86Memory");
+  operandTypes.addEntry("kOperandTypeX86EffectiveAddress");
+  operandTypes.addEntry("kOperandTypeX86PCRelative");
+  operandTypes.addEntry("kOperandTypeARMBranchTarget");
+  operandTypes.addEntry("kOperandTypeARMSoReg");
+  operandTypes.addEntry("kOperandTypeARMSoImm");
+  operandTypes.addEntry("kOperandTypeARMSoImm2Part");
+  operandTypes.addEntry("kOperandTypeARMPredicate");
+  operandTypes.addEntry("kOperandTypeARMAddrMode2");
+  operandTypes.addEntry("kOperandTypeARMAddrMode2Offset");
+  operandTypes.addEntry("kOperandTypeARMAddrMode3");
+  operandTypes.addEntry("kOperandTypeARMAddrMode3Offset");
+  operandTypes.addEntry("kOperandTypeARMAddrMode4");
+  operandTypes.addEntry("kOperandTypeARMAddrMode5");
+  operandTypes.addEntry("kOperandTypeARMAddrMode6");
+  operandTypes.addEntry("kOperandTypeARMAddrMode6Offset");
+  operandTypes.addEntry("kOperandTypeARMAddrModePC");
+  operandTypes.addEntry("kOperandTypeARMRegisterList");
+  operandTypes.addEntry("kOperandTypeARMTBAddrMode");
+  operandTypes.addEntry("kOperandTypeThumbITMask");
+  operandTypes.addEntry("kOperandTypeThumbAddrModeS1");
+  operandTypes.addEntry("kOperandTypeThumbAddrModeS2");
+  operandTypes.addEntry("kOperandTypeThumbAddrModeS4");
+  operandTypes.addEntry("kOperandTypeThumbAddrModeRR");
+  operandTypes.addEntry("kOperandTypeThumbAddrModeSP");
+  operandTypes.addEntry("kOperandTypeThumb2SoReg");
+  operandTypes.addEntry("kOperandTypeThumb2SoImm");
+  operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8");
+  operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8Offset");
+  operandTypes.addEntry("kOperandTypeThumb2AddrModeImm12");
+  operandTypes.addEntry("kOperandTypeThumb2AddrModeSoReg");
+  operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8s4");
+  operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8s4Offset");
+  operandTypes.emit(o, i);
+  
+  o << "\n";
+  
+  EnumEmitter operandFlags("OperandFlags");
+  operandFlags.addEntry("kOperandFlagSource");
+  operandFlags.addEntry("kOperandFlagTarget");
+  operandFlags.emitAsFlags(o, i);
+  
+  o << "\n";
+  
+  EnumEmitter instructionTypes("InstructionTypes");
+  instructionTypes.addEntry("kInstructionTypeNone");
+  instructionTypes.addEntry("kInstructionTypeMove");
+  instructionTypes.addEntry("kInstructionTypeBranch");
+  instructionTypes.addEntry("kInstructionTypePush");
+  instructionTypes.addEntry("kInstructionTypePop");
+  instructionTypes.addEntry("kInstructionTypeCall");
+  instructionTypes.addEntry("kInstructionTypeReturn");
+  instructionTypes.emit(o, i);
+  
+  o << "\n";
+}
+
+void EDEmitter::run(raw_ostream &o) {
+  unsigned int i = 0;
+  
+  CompoundConstantEmitter infoArray;
+  CodeGenTarget target;
+  
+  populateInstInfo(infoArray, target);
+  
+  emitCommonEnums(o, i);
+  
+  o << "namespace {\n";
+  
+  o << "llvm::EDInstInfo instInfo" << target.getName().c_str() << "[] = ";
+  infoArray.emit(o, i);
+  o << ";" << "\n";
+  
+  o << "}\n";
+}
diff --git a/src/LLVM/utils/TableGen/EDEmitter.h b/src/LLVM/utils/TableGen/EDEmitter.h
new file mode 100644
index 0000000..e30373f
--- /dev/null
+++ b/src/LLVM/utils/TableGen/EDEmitter.h
@@ -0,0 +1,34 @@
+//===- EDEmitter.h - Generate instruction descriptions for ED ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend is responsible for emitting a description of each
+// instruction in a format that the semantic disassembler can use to tokenize
+// and parse instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SEMANTIC_INFO_EMITTER_H
+#define SEMANTIC_INFO_EMITTER_H
+
+#include "TableGenBackend.h"
+
+namespace llvm {
+  
+  class EDEmitter : public TableGenBackend {
+    RecordKeeper &Records;
+  public:
+    EDEmitter(RecordKeeper &R);
+    
+    // run - Output the instruction table.
+    void run(raw_ostream &o);
+  };
+  
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/utils/TableGen/FastISelEmitter.cpp b/src/LLVM/utils/TableGen/FastISelEmitter.cpp
new file mode 100644
index 0000000..70448ab
--- /dev/null
+++ b/src/LLVM/utils/TableGen/FastISelEmitter.cpp
@@ -0,0 +1,659 @@
+//===- FastISelEmitter.cpp - Generate an instruction selector -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend emits code for use by the "fast" instruction
+// selection algorithm. See the comments at the top of
+// lib/CodeGen/SelectionDAG/FastISel.cpp for background.
+//
+// This file scans through the target's tablegen instruction-info files
+// and extracts instructions with obvious-looking patterns, and it emits
+// code to look up these instructions by type and operator.
+//
+//===----------------------------------------------------------------------===//
+
+#include "FastISelEmitter.h"
+#include "Record.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/ADT/VectorExtras.h"
+using namespace llvm;
+
+namespace {
+
+/// InstructionMemo - This class holds additional information about an
+/// instruction needed to emit code for it.
+///
+struct InstructionMemo {
+  std::string Name;
+  const CodeGenRegisterClass *RC;
+  std::string SubRegNo;
+  std::vector<std::string>* PhysRegs;
+};
+
+/// OperandsSignature - This class holds a description of a list of operand
+/// types. It has utility methods for emitting text based on the operands.
+///
+struct OperandsSignature {
+  std::vector<std::string> Operands;
+
+  bool operator<(const OperandsSignature &O) const {
+    return Operands < O.Operands;
+  }
+
+  bool empty() const { return Operands.empty(); }
+
+  /// initialize - Examine the given pattern and initialize the contents
+  /// of the Operands array accordingly. Return true if all the operands
+  /// are supported, false otherwise.
+  ///
+  bool initialize(TreePatternNode *InstPatNode,
+                  const CodeGenTarget &Target,
+                  MVT::SimpleValueType VT) {
+
+    if (!InstPatNode->isLeaf()) {
+      if (InstPatNode->getOperator()->getName() == "imm") {
+        Operands.push_back("i");
+        return true;
+      }
+      if (InstPatNode->getOperator()->getName() == "fpimm") {
+        Operands.push_back("f");
+        return true;
+      }
+    }
+    
+    const CodeGenRegisterClass *DstRC = 0;
+    
+    for (unsigned i = 0, e = InstPatNode->getNumChildren(); i != e; ++i) {
+      TreePatternNode *Op = InstPatNode->getChild(i);
+      
+      // For now, filter out any operand with a predicate.
+      // For now, filter out any operand with multiple values.
+      if (!Op->getPredicateFns().empty() ||
+          Op->getNumTypes() != 1)
+        return false;
+      
+      assert(Op->hasTypeSet(0) && "Type infererence not done?");
+      // For now, all the operands must have the same type.
+      if (Op->getType(0) != VT)
+        return false;
+      
+      if (!Op->isLeaf()) {
+        if (Op->getOperator()->getName() == "imm") {
+          Operands.push_back("i");
+          continue;
+        }
+        if (Op->getOperator()->getName() == "fpimm") {
+          Operands.push_back("f");
+          continue;
+        }
+        // For now, ignore other non-leaf nodes.
+        return false;
+      }
+      DefInit *OpDI = dynamic_cast<DefInit*>(Op->getLeafValue());
+      if (!OpDI)
+        return false;
+      Record *OpLeafRec = OpDI->getDef();
+      // For now, the only other thing we accept is register operands.
+
+      const CodeGenRegisterClass *RC = 0;
+      if (OpLeafRec->isSubClassOf("RegisterClass"))
+        RC = &Target.getRegisterClass(OpLeafRec);
+      else if (OpLeafRec->isSubClassOf("Register"))
+        RC = Target.getRegisterClassForRegister(OpLeafRec);
+      else
+        return false;
+        
+      // For now, require the register operands' register classes to all
+      // be the same.
+      if (!RC)
+        return false;
+      // For now, all the operands must have the same register class.
+      if (DstRC) {
+        if (DstRC != RC)
+          return false;
+      } else
+        DstRC = RC;
+      Operands.push_back("r");
+    }
+    return true;
+  }
+
+  void PrintParameters(raw_ostream &OS) const {
+    for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
+      if (Operands[i] == "r") {
+        OS << "unsigned Op" << i << ", bool Op" << i << "IsKill";
+      } else if (Operands[i] == "i") {
+        OS << "uint64_t imm" << i;
+      } else if (Operands[i] == "f") {
+        OS << "ConstantFP *f" << i;
+      } else {
+        assert("Unknown operand kind!");
+        abort();
+      }
+      if (i + 1 != e)
+        OS << ", ";
+    }
+  }
+
+  void PrintArguments(raw_ostream &OS,
+                      const std::vector<std::string>& PR) const {
+    assert(PR.size() == Operands.size());
+    bool PrintedArg = false;
+    for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
+      if (PR[i] != "")
+        // Implicit physical register operand.
+        continue;
+
+      if (PrintedArg)
+        OS << ", ";
+      if (Operands[i] == "r") {
+        OS << "Op" << i << ", Op" << i << "IsKill";
+        PrintedArg = true;
+      } else if (Operands[i] == "i") {
+        OS << "imm" << i;
+        PrintedArg = true;
+      } else if (Operands[i] == "f") {
+        OS << "f" << i;
+        PrintedArg = true;
+      } else {
+        assert("Unknown operand kind!");
+        abort();
+      }
+    }
+  }
+
+  void PrintArguments(raw_ostream &OS) const {
+    for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
+      if (Operands[i] == "r") {
+        OS << "Op" << i << ", Op" << i << "IsKill";
+      } else if (Operands[i] == "i") {
+        OS << "imm" << i;
+      } else if (Operands[i] == "f") {
+        OS << "f" << i;
+      } else {
+        assert("Unknown operand kind!");
+        abort();
+      }
+      if (i + 1 != e)
+        OS << ", ";
+    }
+  }
+
+
+  void PrintManglingSuffix(raw_ostream &OS,
+                           const std::vector<std::string>& PR) const {
+    for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
+      if (PR[i] != "")
+        // Implicit physical register operand. e.g. Instruction::Mul expect to
+        // select to a binary op. On x86, mul may take a single operand with
+        // the other operand being implicit. We must emit something that looks
+        // like a binary instruction except for the very inner FastEmitInst_*
+        // call.
+        continue;
+      OS << Operands[i];
+    }
+  }
+
+  void PrintManglingSuffix(raw_ostream &OS) const {
+    for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
+      OS << Operands[i];
+    }
+  }
+};
+
+class FastISelMap {
+  typedef std::map<std::string, InstructionMemo> PredMap;
+  typedef std::map<MVT::SimpleValueType, PredMap> RetPredMap;
+  typedef std::map<MVT::SimpleValueType, RetPredMap> TypeRetPredMap;
+  typedef std::map<std::string, TypeRetPredMap> OpcodeTypeRetPredMap;
+  typedef std::map<OperandsSignature, OpcodeTypeRetPredMap> 
+            OperandsOpcodeTypeRetPredMap;
+
+  OperandsOpcodeTypeRetPredMap SimplePatterns;
+
+  std::string InstNS;
+
+public:
+  explicit FastISelMap(std::string InstNS);
+
+  void CollectPatterns(CodeGenDAGPatterns &CGP);
+  void PrintFunctionDefinitions(raw_ostream &OS);
+};
+
+}
+
+static std::string getOpcodeName(Record *Op, CodeGenDAGPatterns &CGP) {
+  return CGP.getSDNodeInfo(Op).getEnumName();
+}
+
+static std::string getLegalCName(std::string OpName) {
+  std::string::size_type pos = OpName.find("::");
+  if (pos != std::string::npos)
+    OpName.replace(pos, 2, "_");
+  return OpName;
+}
+
+FastISelMap::FastISelMap(std::string instns)
+  : InstNS(instns) {
+}
+
+void FastISelMap::CollectPatterns(CodeGenDAGPatterns &CGP) {
+  const CodeGenTarget &Target = CGP.getTargetInfo();
+
+  // Determine the target's namespace name.
+  InstNS = Target.getInstNamespace() + "::";
+  assert(InstNS.size() > 2 && "Can't determine target-specific namespace!");
+
+  // Scan through all the patterns and record the simple ones.
+  for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(),
+       E = CGP.ptm_end(); I != E; ++I) {
+    const PatternToMatch &Pattern = *I;
+
+    // For now, just look at Instructions, so that we don't have to worry
+    // about emitting multiple instructions for a pattern.
+    TreePatternNode *Dst = Pattern.getDstPattern();
+    if (Dst->isLeaf()) continue;
+    Record *Op = Dst->getOperator();
+    if (!Op->isSubClassOf("Instruction"))
+      continue;
+    CodeGenInstruction &II = CGP.getTargetInfo().getInstruction(Op);
+    if (II.OperandList.empty())
+      continue;
+
+    // For now ignore instructions that have predicate operands.
+    bool HasPredicate = false;
+    for (unsigned i = 0, e = II.OperandList.size(); i != e; ++i) {
+      if(II.OperandList[i].Rec->isSubClassOf("PredicateOperand"))
+        HasPredicate = true;
+    }
+    if (HasPredicate)
+      continue;
+      
+    // For now, ignore multi-instruction patterns.
+    bool MultiInsts = false;
+    for (unsigned i = 0, e = Dst->getNumChildren(); i != e; ++i) {
+      TreePatternNode *ChildOp = Dst->getChild(i);
+      if (ChildOp->isLeaf())
+        continue;
+      if (ChildOp->getOperator()->isSubClassOf("Instruction")) {
+        MultiInsts = true;
+        break;
+      }
+    }
+    if (MultiInsts)
+      continue;
+
+    // For now, ignore instructions where the first operand is not an
+    // output register.
+    const CodeGenRegisterClass *DstRC = 0;
+    std::string SubRegNo;
+    if (Op->getName() != "EXTRACT_SUBREG") {
+      Record *Op0Rec = II.OperandList[0].Rec;
+      if (!Op0Rec->isSubClassOf("RegisterClass"))
+        continue;
+      DstRC = &Target.getRegisterClass(Op0Rec);
+      if (!DstRC)
+        continue;
+    } else {
+      // If this isn't a leaf, then continue since the register classes are
+      // a bit too complicated for now.
+      if (!Dst->getChild(1)->isLeaf()) continue;
+      
+      DefInit *SR = dynamic_cast<DefInit*>(Dst->getChild(1)->getLeafValue());
+      if (SR)
+        SubRegNo = getQualifiedName(SR->getDef());
+      else
+        SubRegNo = Dst->getChild(1)->getLeafValue()->getAsString();
+    }
+
+    // Inspect the pattern.
+    TreePatternNode *InstPatNode = Pattern.getSrcPattern();
+    if (!InstPatNode) continue;
+    if (InstPatNode->isLeaf()) continue;
+
+    // Ignore multiple result nodes for now.
+    if (InstPatNode->getNumTypes() > 1) continue;
+    
+    Record *InstPatOp = InstPatNode->getOperator();
+    std::string OpcodeName = getOpcodeName(InstPatOp, CGP);
+    MVT::SimpleValueType RetVT = MVT::isVoid;
+    if (InstPatNode->getNumTypes()) RetVT = InstPatNode->getType(0);
+    MVT::SimpleValueType VT = RetVT;
+    if (InstPatNode->getNumChildren()) {
+      assert(InstPatNode->getChild(0)->getNumTypes() == 1);
+      VT = InstPatNode->getChild(0)->getType(0);
+    }
+
+    // For now, filter out instructions which just set a register to
+    // an Operand or an immediate, like MOV32ri.
+    if (InstPatOp->isSubClassOf("Operand"))
+      continue;
+
+    // For now, filter out any instructions with predicates.
+    if (!InstPatNode->getPredicateFns().empty())
+      continue;
+
+    // Check all the operands.
+    OperandsSignature Operands;
+    if (!Operands.initialize(InstPatNode, Target, VT))
+      continue;
+    
+    std::vector<std::string>* PhysRegInputs = new std::vector<std::string>();
+    if (!InstPatNode->isLeaf() &&
+        (InstPatNode->getOperator()->getName() == "imm" ||
+         InstPatNode->getOperator()->getName() == "fpimmm"))
+      PhysRegInputs->push_back("");
+    else if (!InstPatNode->isLeaf()) {
+      for (unsigned i = 0, e = InstPatNode->getNumChildren(); i != e; ++i) {
+        TreePatternNode *Op = InstPatNode->getChild(i);
+        if (!Op->isLeaf()) {
+          PhysRegInputs->push_back("");
+          continue;
+        }
+        
+        DefInit *OpDI = dynamic_cast<DefInit*>(Op->getLeafValue());
+        Record *OpLeafRec = OpDI->getDef();
+        std::string PhysReg;
+        if (OpLeafRec->isSubClassOf("Register")) {
+          PhysReg += static_cast<StringInit*>(OpLeafRec->getValue( \
+                     "Namespace")->getValue())->getValue();
+          PhysReg += "::";
+          
+          std::vector<CodeGenRegister> Regs = Target.getRegisters();
+          for (unsigned i = 0; i < Regs.size(); ++i) {
+            if (Regs[i].TheDef == OpLeafRec) {
+              PhysReg += Regs[i].getName();
+              break;
+            }
+          }
+        }
+      
+        PhysRegInputs->push_back(PhysReg);
+      }
+    } else
+      PhysRegInputs->push_back("");
+
+    // Get the predicate that guards this pattern.
+    std::string PredicateCheck = Pattern.getPredicateCheck();
+
+    // Ok, we found a pattern that we can handle. Remember it.
+    InstructionMemo Memo = {
+      Pattern.getDstPattern()->getOperator()->getName(),
+      DstRC,
+      SubRegNo,
+      PhysRegInputs
+    };
+    assert(!SimplePatterns[Operands][OpcodeName][VT][RetVT]
+            .count(PredicateCheck) &&
+           "Duplicate pattern!");
+    SimplePatterns[Operands][OpcodeName][VT][RetVT][PredicateCheck] = Memo;
+  }
+}
+
+void FastISelMap::PrintFunctionDefinitions(raw_ostream &OS) {
+  // Now emit code for all the patterns that we collected.
+  for (OperandsOpcodeTypeRetPredMap::const_iterator OI = SimplePatterns.begin(),
+       OE = SimplePatterns.end(); OI != OE; ++OI) {
+    const OperandsSignature &Operands = OI->first;
+    const OpcodeTypeRetPredMap &OTM = OI->second;
+
+    for (OpcodeTypeRetPredMap::const_iterator I = OTM.begin(), E = OTM.end();
+         I != E; ++I) {
+      const std::string &Opcode = I->first;
+      const TypeRetPredMap &TM = I->second;
+
+      OS << "// FastEmit functions for " << Opcode << ".\n";
+      OS << "\n";
+
+      // Emit one function for each opcode,type pair.
+      for (TypeRetPredMap::const_iterator TI = TM.begin(), TE = TM.end();
+           TI != TE; ++TI) {
+        MVT::SimpleValueType VT = TI->first;
+        const RetPredMap &RM = TI->second;
+        if (RM.size() != 1) {
+          for (RetPredMap::const_iterator RI = RM.begin(), RE = RM.end();
+               RI != RE; ++RI) {
+            MVT::SimpleValueType RetVT = RI->first;
+            const PredMap &PM = RI->second;
+            bool HasPred = false;
+
+            OS << "unsigned FastEmit_"
+               << getLegalCName(Opcode)
+               << "_" << getLegalCName(getName(VT))
+               << "_" << getLegalCName(getName(RetVT)) << "_";
+            Operands.PrintManglingSuffix(OS);
+            OS << "(";
+            Operands.PrintParameters(OS);
+            OS << ") {\n";
+
+            // Emit code for each possible instruction. There may be
+            // multiple if there are subtarget concerns.
+            for (PredMap::const_iterator PI = PM.begin(), PE = PM.end();
+                 PI != PE; ++PI) {
+              std::string PredicateCheck = PI->first;
+              const InstructionMemo &Memo = PI->second;
+  
+              if (PredicateCheck.empty()) {
+                assert(!HasPred &&
+                       "Multiple instructions match, at least one has "
+                       "a predicate and at least one doesn't!");
+              } else {
+                OS << "  if (" + PredicateCheck + ") {\n";
+                OS << "  ";
+                HasPred = true;
+              }
+              
+              for (unsigned i = 0; i < Memo.PhysRegs->size(); ++i) {
+                if ((*Memo.PhysRegs)[i] != "")
+                  OS << "  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, "
+                     << "TII.get(TargetOpcode::COPY), "
+                     << (*Memo.PhysRegs)[i] << ").addReg(Op" << i << ");\n";
+              }
+              
+              OS << "  return FastEmitInst_";
+              if (Memo.SubRegNo.empty()) {
+                Operands.PrintManglingSuffix(OS, *Memo.PhysRegs);
+                OS << "(" << InstNS << Memo.Name << ", ";
+                OS << InstNS << Memo.RC->getName() << "RegisterClass";
+                if (!Operands.empty())
+                  OS << ", ";
+                Operands.PrintArguments(OS, *Memo.PhysRegs);
+                OS << ");\n";
+              } else {
+                OS << "extractsubreg(" << getName(RetVT);
+                OS << ", Op0, Op0IsKill, ";
+                OS << Memo.SubRegNo;
+                OS << ");\n";
+              }
+              
+              if (HasPred)
+                OS << "  }\n";
+              
+            }
+            // Return 0 if none of the predicates were satisfied.
+            if (HasPred)
+              OS << "  return 0;\n";
+            OS << "}\n";
+            OS << "\n";
+          }
+          
+          // Emit one function for the type that demultiplexes on return type.
+          OS << "unsigned FastEmit_"
+             << getLegalCName(Opcode) << "_"
+             << getLegalCName(getName(VT)) << "_";
+          Operands.PrintManglingSuffix(OS);
+          OS << "(MVT RetVT";
+          if (!Operands.empty())
+            OS << ", ";
+          Operands.PrintParameters(OS);
+          OS << ") {\nswitch (RetVT.SimpleTy) {\n";
+          for (RetPredMap::const_iterator RI = RM.begin(), RE = RM.end();
+               RI != RE; ++RI) {
+            MVT::SimpleValueType RetVT = RI->first;
+            OS << "  case " << getName(RetVT) << ": return FastEmit_"
+               << getLegalCName(Opcode) << "_" << getLegalCName(getName(VT))
+               << "_" << getLegalCName(getName(RetVT)) << "_";
+            Operands.PrintManglingSuffix(OS);
+            OS << "(";
+            Operands.PrintArguments(OS);
+            OS << ");\n";
+          }
+          OS << "  default: return 0;\n}\n}\n\n";
+          
+        } else {
+          // Non-variadic return type.
+          OS << "unsigned FastEmit_"
+             << getLegalCName(Opcode) << "_"
+             << getLegalCName(getName(VT)) << "_";
+          Operands.PrintManglingSuffix(OS);
+          OS << "(MVT RetVT";
+          if (!Operands.empty())
+            OS << ", ";
+          Operands.PrintParameters(OS);
+          OS << ") {\n";
+          
+          OS << "  if (RetVT.SimpleTy != " << getName(RM.begin()->first)
+             << ")\n    return 0;\n";
+          
+          const PredMap &PM = RM.begin()->second;
+          bool HasPred = false;
+          
+          // Emit code for each possible instruction. There may be
+          // multiple if there are subtarget concerns.
+          for (PredMap::const_iterator PI = PM.begin(), PE = PM.end(); PI != PE;
+               ++PI) {
+            std::string PredicateCheck = PI->first;
+            const InstructionMemo &Memo = PI->second;
+
+            if (PredicateCheck.empty()) {
+              assert(!HasPred &&
+                     "Multiple instructions match, at least one has "
+                     "a predicate and at least one doesn't!");
+            } else {
+              OS << "  if (" + PredicateCheck + ") {\n";
+              OS << "  ";
+              HasPred = true;
+            }
+            
+            for (unsigned i = 0; i < Memo.PhysRegs->size(); ++i) {
+              if ((*Memo.PhysRegs)[i] != "")
+                OS << "  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, "
+                   << "TII.get(TargetOpcode::COPY), "
+                   << (*Memo.PhysRegs)[i] << ").addReg(Op" << i << ");\n";
+            }
+            
+            OS << "  return FastEmitInst_";
+            
+            if (Memo.SubRegNo.empty()) {
+              Operands.PrintManglingSuffix(OS, *Memo.PhysRegs);
+              OS << "(" << InstNS << Memo.Name << ", ";
+              OS << InstNS << Memo.RC->getName() << "RegisterClass";
+              if (!Operands.empty())
+                OS << ", ";
+              Operands.PrintArguments(OS, *Memo.PhysRegs);
+              OS << ");\n";
+            } else {
+              OS << "extractsubreg(RetVT, Op0, Op0IsKill, ";
+              OS << Memo.SubRegNo;
+              OS << ");\n";
+            }
+            
+             if (HasPred)
+               OS << "  }\n";
+          }
+          
+          // Return 0 if none of the predicates were satisfied.
+          if (HasPred)
+            OS << "  return 0;\n";
+          OS << "}\n";
+          OS << "\n";
+        }
+      }
+
+      // Emit one function for the opcode that demultiplexes based on the type.
+      OS << "unsigned FastEmit_"
+         << getLegalCName(Opcode) << "_";
+      Operands.PrintManglingSuffix(OS);
+      OS << "(MVT VT, MVT RetVT";
+      if (!Operands.empty())
+        OS << ", ";
+      Operands.PrintParameters(OS);
+      OS << ") {\n";
+      OS << "  switch (VT.SimpleTy) {\n";
+      for (TypeRetPredMap::const_iterator TI = TM.begin(), TE = TM.end();
+           TI != TE; ++TI) {
+        MVT::SimpleValueType VT = TI->first;
+        std::string TypeName = getName(VT);
+        OS << "  case " << TypeName << ": return FastEmit_"
+           << getLegalCName(Opcode) << "_" << getLegalCName(TypeName) << "_";
+        Operands.PrintManglingSuffix(OS);
+        OS << "(RetVT";
+        if (!Operands.empty())
+          OS << ", ";
+        Operands.PrintArguments(OS);
+        OS << ");\n";
+      }
+      OS << "  default: return 0;\n";
+      OS << "  }\n";
+      OS << "}\n";
+      OS << "\n";
+    }
+
+    OS << "// Top-level FastEmit function.\n";
+    OS << "\n";
+
+    // Emit one function for the operand signature that demultiplexes based
+    // on opcode and type.
+    OS << "unsigned FastEmit_";
+    Operands.PrintManglingSuffix(OS);
+    OS << "(MVT VT, MVT RetVT, unsigned Opcode";
+    if (!Operands.empty())
+      OS << ", ";
+    Operands.PrintParameters(OS);
+    OS << ") {\n";
+    OS << "  switch (Opcode) {\n";
+    for (OpcodeTypeRetPredMap::const_iterator I = OTM.begin(), E = OTM.end();
+         I != E; ++I) {
+      const std::string &Opcode = I->first;
+
+      OS << "  case " << Opcode << ": return FastEmit_"
+         << getLegalCName(Opcode) << "_";
+      Operands.PrintManglingSuffix(OS);
+      OS << "(VT, RetVT";
+      if (!Operands.empty())
+        OS << ", ";
+      Operands.PrintArguments(OS);
+      OS << ");\n";
+    }
+    OS << "  default: return 0;\n";
+    OS << "  }\n";
+    OS << "}\n";
+    OS << "\n";
+  }
+}
+
+void FastISelEmitter::run(raw_ostream &OS) {
+  const CodeGenTarget &Target = CGP.getTargetInfo();
+
+  // Determine the target's namespace name.
+  std::string InstNS = Target.getInstNamespace() + "::";
+  assert(InstNS.size() > 2 && "Can't determine target-specific namespace!");
+
+  EmitSourceFileHeader("\"Fast\" Instruction Selector for the " +
+                       Target.getName() + " target", OS);
+
+  FastISelMap F(InstNS);
+  F.CollectPatterns(CGP);
+  F.PrintFunctionDefinitions(OS);
+}
+
+FastISelEmitter::FastISelEmitter(RecordKeeper &R)
+  : Records(R),
+    CGP(R) {
+}
+
diff --git a/src/LLVM/utils/TableGen/FastISelEmitter.h b/src/LLVM/utils/TableGen/FastISelEmitter.h
new file mode 100644
index 0000000..ce4e77e
--- /dev/null
+++ b/src/LLVM/utils/TableGen/FastISelEmitter.h
@@ -0,0 +1,39 @@
+//===- FastISelEmitter.h - Generate an instruction selector -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend emits a "fast" instruction selector.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FASTISEL_EMITTER_H
+#define FASTISEL_EMITTER_H
+
+#include "TableGenBackend.h"
+#include "CodeGenDAGPatterns.h"
+
+namespace llvm {
+
+class CodeGenTarget;
+
+/// FastISelEmitter - The top-level class which coordinates construction
+/// and emission of the instruction selector.
+///
+class FastISelEmitter : public TableGenBackend {
+  RecordKeeper &Records;
+  CodeGenDAGPatterns CGP;
+public:
+  explicit FastISelEmitter(RecordKeeper &R);
+
+  // run - Output the isel, returning true on failure.
+  void run(raw_ostream &OS);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/utils/TableGen/InstrEnumEmitter.cpp b/src/LLVM/utils/TableGen/InstrEnumEmitter.cpp
new file mode 100644
index 0000000..47a8474
--- /dev/null
+++ b/src/LLVM/utils/TableGen/InstrEnumEmitter.cpp
@@ -0,0 +1,48 @@
+//===- InstrEnumEmitter.cpp - Generate Instruction Set Enums --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend is responsible for emitting enums for each machine
+// instruction.
+//
+//===----------------------------------------------------------------------===//
+
+#include "InstrEnumEmitter.h"
+#include "CodeGenTarget.h"
+#include "Record.h"
+#include <cstdio>
+using namespace llvm;
+
+// runEnums - Print out enum values for all of the instructions.
+void InstrEnumEmitter::run(raw_ostream &OS) {
+  EmitSourceFileHeader("Target Instruction Enum Values", OS);
+  OS << "namespace llvm {\n\n";
+
+  CodeGenTarget Target;
+
+  // We must emit the PHI opcode first...
+  std::string Namespace = Target.getInstNamespace();
+  
+  if (Namespace.empty()) {
+    fprintf(stderr, "No instructions defined!\n");
+    exit(1);
+  }
+
+  const std::vector<const CodeGenInstruction*> &NumberedInstructions =
+    Target.getInstructionsByEnumValue();
+
+  OS << "namespace " << Namespace << " {\n";
+  OS << "  enum {\n";
+  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
+    OS << "    " << NumberedInstructions[i]->TheDef->getName()
+       << "\t= " << i << ",\n";
+  }
+  OS << "    INSTRUCTION_LIST_END = " << NumberedInstructions.size() << "\n";
+  OS << "  };\n}\n";
+  OS << "} // End llvm namespace \n";
+}
diff --git a/src/LLVM/utils/TableGen/InstrEnumEmitter.h b/src/LLVM/utils/TableGen/InstrEnumEmitter.h
new file mode 100644
index 0000000..89f8b65
--- /dev/null
+++ b/src/LLVM/utils/TableGen/InstrEnumEmitter.h
@@ -0,0 +1,33 @@
+//===- InstrEnumEmitter.h - Generate Instruction Set Enums ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend is responsible for emitting enums for each machine
+// instruction.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef INSTRENUM_EMITTER_H
+#define INSTRENUM_EMITTER_H
+
+#include "TableGenBackend.h"
+
+namespace llvm {
+
+class InstrEnumEmitter : public TableGenBackend {
+  RecordKeeper &Records;
+public:
+  InstrEnumEmitter(RecordKeeper &R) : Records(R) {}
+
+  // run - Output the instruction set description, returning true on failure.
+  void run(raw_ostream &OS);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/utils/TableGen/InstrInfoEmitter.cpp b/src/LLVM/utils/TableGen/InstrInfoEmitter.cpp
new file mode 100644
index 0000000..4d3aa5e
--- /dev/null
+++ b/src/LLVM/utils/TableGen/InstrInfoEmitter.cpp
@@ -0,0 +1,335 @@
+//===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend is responsible for emitting a description of the target
+// instruction set for the code generator.
+//
+//===----------------------------------------------------------------------===//
+
+#include "InstrInfoEmitter.h"
+#include "CodeGenTarget.h"
+#include "Record.h"
+#include "llvm/ADT/StringExtras.h"
+#include <algorithm>
+using namespace llvm;
+
+static void PrintDefList(const std::vector<Record*> &Uses,
+                         unsigned Num, raw_ostream &OS) {
+  OS << "static const unsigned ImplicitList" << Num << "[] = { ";
+  for (unsigned i = 0, e = Uses.size(); i != e; ++i)
+    OS << getQualifiedName(Uses[i]) << ", ";
+  OS << "0 };\n";
+}
+
+static void PrintBarriers(std::vector<Record*> &Barriers,
+                          unsigned Num, raw_ostream &OS) {
+  OS << "static const TargetRegisterClass* Barriers" << Num << "[] = { ";
+  for (unsigned i = 0, e = Barriers.size(); i != e; ++i)
+    OS << "&" << getQualifiedName(Barriers[i]) << "RegClass, ";
+  OS << "NULL };\n";
+}
+
+//===----------------------------------------------------------------------===//
+// Instruction Itinerary Information.
+//===----------------------------------------------------------------------===//
+
+void InstrInfoEmitter::GatherItinClasses() {
+  std::vector<Record*> DefList =
+  Records.getAllDerivedDefinitions("InstrItinClass");
+  std::sort(DefList.begin(), DefList.end(), LessRecord());
+  
+  for (unsigned i = 0, N = DefList.size(); i < N; i++)
+    ItinClassMap[DefList[i]->getName()] = i;
+}  
+
+unsigned InstrInfoEmitter::getItinClassNumber(const Record *InstRec) {
+  return ItinClassMap[InstRec->getValueAsDef("Itinerary")->getName()];
+}
+
+//===----------------------------------------------------------------------===//
+// Operand Info Emission.
+//===----------------------------------------------------------------------===//
+
+std::vector<std::string>
+InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
+  std::vector<std::string> Result;
+  
+  for (unsigned i = 0, e = Inst.OperandList.size(); i != e; ++i) {
+    // Handle aggregate operands and normal operands the same way by expanding
+    // either case into a list of operands for this op.
+    std::vector<CodeGenInstruction::OperandInfo> OperandList;
+
+    // This might be a multiple operand thing.  Targets like X86 have
+    // registers in their multi-operand operands.  It may also be an anonymous
+    // operand, which has a single operand, but no declared class for the
+    // operand.
+    DagInit *MIOI = Inst.OperandList[i].MIOperandInfo;
+    
+    if (!MIOI || MIOI->getNumArgs() == 0) {
+      // Single, anonymous, operand.
+      OperandList.push_back(Inst.OperandList[i]);
+    } else {
+      for (unsigned j = 0, e = Inst.OperandList[i].MINumOperands; j != e; ++j) {
+        OperandList.push_back(Inst.OperandList[i]);
+
+        Record *OpR = dynamic_cast<DefInit*>(MIOI->getArg(j))->getDef();
+        OperandList.back().Rec = OpR;
+      }
+    }
+
+    for (unsigned j = 0, e = OperandList.size(); j != e; ++j) {
+      Record *OpR = OperandList[j].Rec;
+      std::string Res;
+      
+      if (OpR->isSubClassOf("RegisterClass"))
+        Res += getQualifiedName(OpR) + "RegClassID, ";
+      else if (OpR->isSubClassOf("PointerLikeRegClass"))
+        Res += utostr(OpR->getValueAsInt("RegClassKind")) + ", ";
+      else
+        // -1 means the operand does not have a fixed register class.
+        Res += "-1, ";
+      
+      // Fill in applicable flags.
+      Res += "0";
+        
+      // Ptr value whose register class is resolved via callback.
+      if (OpR->isSubClassOf("PointerLikeRegClass"))
+        Res += "|(1<<TOI::LookupPtrRegClass)";
+
+      // Predicate operands.  Check to see if the original unexpanded operand
+      // was of type PredicateOperand.
+      if (Inst.OperandList[i].Rec->isSubClassOf("PredicateOperand"))
+        Res += "|(1<<TOI::Predicate)";
+        
+      // Optional def operands.  Check to see if the original unexpanded operand
+      // was of type OptionalDefOperand.
+      if (Inst.OperandList[i].Rec->isSubClassOf("OptionalDefOperand"))
+        Res += "|(1<<TOI::OptionalDef)";
+
+      // Fill in constraint info.
+      Res += ", ";
+      
+      const CodeGenInstruction::ConstraintInfo &Constraint =
+        Inst.OperandList[i].Constraints[j];
+      if (Constraint.isNone())
+        Res += "0";
+      else if (Constraint.isEarlyClobber())
+        Res += "(1 << TOI::EARLY_CLOBBER)";
+      else {
+        assert(Constraint.isTied());
+        Res += "((" + utostr(Constraint.getTiedOperand()) +
+                    " << 16) | (1 << TOI::TIED_TO))";
+      }
+        
+      Result.push_back(Res);
+    }
+  }
+
+  return Result;
+}
+
+void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS, 
+                                       OperandInfoMapTy &OperandInfoIDs) {
+  // ID #0 is for no operand info.
+  unsigned OperandListNum = 0;
+  OperandInfoIDs[std::vector<std::string>()] = ++OperandListNum;
+  
+  OS << "\n";
+  const CodeGenTarget &Target = CDP.getTargetInfo();
+  for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
+       E = Target.inst_end(); II != E; ++II) {
+    std::vector<std::string> OperandInfo = GetOperandInfo(**II);
+    unsigned &N = OperandInfoIDs[OperandInfo];
+    if (N != 0) continue;
+    
+    N = ++OperandListNum;
+    OS << "static const TargetOperandInfo OperandInfo" << N << "[] = { ";
+    for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i)
+      OS << "{ " << OperandInfo[i] << " }, ";
+    OS << "};\n";
+  }
+}
+
+void InstrInfoEmitter::DetectRegisterClassBarriers(std::vector<Record*> &Defs,
+                                  const std::vector<CodeGenRegisterClass> &RCs,
+                                  std::vector<Record*> &Barriers) {
+  std::set<Record*> DefSet;
+  unsigned NumDefs = Defs.size();
+  for (unsigned i = 0; i < NumDefs; ++i)
+    DefSet.insert(Defs[i]);
+
+  for (unsigned i = 0, e = RCs.size(); i != e; ++i) {
+    const CodeGenRegisterClass &RC = RCs[i];
+    unsigned NumRegs = RC.Elements.size();
+    if (NumRegs > NumDefs)
+      continue; // Can't possibly clobber this RC.
+
+    bool Clobber = true;
+    for (unsigned j = 0; j < NumRegs; ++j) {
+      Record *Reg = RC.Elements[j];
+      if (!DefSet.count(Reg)) {
+        Clobber = false;
+        break;
+      }
+    }
+    if (Clobber)
+      Barriers.push_back(RC.TheDef);
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Main Output.
+//===----------------------------------------------------------------------===//
+
+// run - Emit the main instruction description records for the target...
+void InstrInfoEmitter::run(raw_ostream &OS) {
+  GatherItinClasses();
+
+  EmitSourceFileHeader("Target Instruction Descriptors", OS);
+  OS << "namespace llvm {\n\n";
+
+  CodeGenTarget &Target = CDP.getTargetInfo();
+  const std::string &TargetName = Target.getName();
+  Record *InstrInfo = Target.getInstructionSet();
+  const std::vector<CodeGenRegisterClass> &RCs = Target.getRegisterClasses();
+
+  // Keep track of all of the def lists we have emitted already.
+  std::map<std::vector<Record*>, unsigned> EmittedLists;
+  unsigned ListNumber = 0;
+  std::map<std::vector<Record*>, unsigned> EmittedBarriers;
+  unsigned BarrierNumber = 0;
+  std::map<Record*, unsigned> BarriersMap;
+ 
+  // Emit all of the instruction's implicit uses and defs.
+  for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
+         E = Target.inst_end(); II != E; ++II) {
+    Record *Inst = (*II)->TheDef;
+    std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses");
+    if (!Uses.empty()) {
+      unsigned &IL = EmittedLists[Uses];
+      if (!IL) PrintDefList(Uses, IL = ++ListNumber, OS);
+    }
+    std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs");
+    if (!Defs.empty()) {
+      std::vector<Record*> RCBarriers;
+      DetectRegisterClassBarriers(Defs, RCs, RCBarriers);
+      if (!RCBarriers.empty()) {
+        unsigned &IB = EmittedBarriers[RCBarriers];
+        if (!IB) PrintBarriers(RCBarriers, IB = ++BarrierNumber, OS);
+        BarriersMap.insert(std::make_pair(Inst, IB));
+      }
+
+      unsigned &IL = EmittedLists[Defs];
+      if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS);
+    }
+  }
+
+  OperandInfoMapTy OperandInfoIDs;
+  
+  // Emit all of the operand info records.
+  EmitOperandInfo(OS, OperandInfoIDs);
+  
+  // Emit all of the TargetInstrDesc records in their ENUM ordering.
+  //
+  OS << "\nstatic const TargetInstrDesc " << TargetName
+     << "Insts[] = {\n";
+  const std::vector<const CodeGenInstruction*> &NumberedInstructions =
+    Target.getInstructionsByEnumValue();
+
+  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i)
+    emitRecord(*NumberedInstructions[i], i, InstrInfo, EmittedLists,
+               BarriersMap, OperandInfoIDs, OS);
+  OS << "};\n";
+  OS << "} // End llvm namespace \n";
+}
+
+void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
+                                  Record *InstrInfo,
+                         std::map<std::vector<Record*>, unsigned> &EmittedLists,
+                                  std::map<Record*, unsigned> &BarriersMap,
+                                  const OperandInfoMapTy &OpInfo,
+                                  raw_ostream &OS) {
+  int MinOperands = 0;
+  if (!Inst.OperandList.empty())
+    // Each logical operand can be multiple MI operands.
+    MinOperands = Inst.OperandList.back().MIOperandNo +
+                  Inst.OperandList.back().MINumOperands;
+
+  OS << "  { ";
+  OS << Num << ",\t" << MinOperands << ",\t"
+     << Inst.NumDefs << ",\t" << getItinClassNumber(Inst.TheDef)
+     << ",\t\"" << Inst.TheDef->getName() << "\", 0";
+
+  // Emit all of the target indepedent flags...
+  if (Inst.isReturn)           OS << "|(1<<TID::Return)";
+  if (Inst.isBranch)           OS << "|(1<<TID::Branch)";
+  if (Inst.isIndirectBranch)   OS << "|(1<<TID::IndirectBranch)";
+  if (Inst.isCompare)          OS << "|(1<<TID::Compare)";
+  if (Inst.isBarrier)          OS << "|(1<<TID::Barrier)";
+  if (Inst.hasDelaySlot)       OS << "|(1<<TID::DelaySlot)";
+  if (Inst.isCall)             OS << "|(1<<TID::Call)";
+  if (Inst.canFoldAsLoad)      OS << "|(1<<TID::FoldableAsLoad)";
+  if (Inst.mayLoad)            OS << "|(1<<TID::MayLoad)";
+  if (Inst.mayStore)           OS << "|(1<<TID::MayStore)";
+  if (Inst.isPredicable)       OS << "|(1<<TID::Predicable)";
+  if (Inst.isConvertibleToThreeAddress) OS << "|(1<<TID::ConvertibleTo3Addr)";
+  if (Inst.isCommutable)       OS << "|(1<<TID::Commutable)";
+  if (Inst.isTerminator)       OS << "|(1<<TID::Terminator)";
+  if (Inst.isReMaterializable) OS << "|(1<<TID::Rematerializable)";
+  if (Inst.isNotDuplicable)    OS << "|(1<<TID::NotDuplicable)";
+  if (Inst.hasOptionalDef)     OS << "|(1<<TID::HasOptionalDef)";
+  if (Inst.usesCustomInserter) OS << "|(1<<TID::UsesCustomInserter)";
+  if (Inst.isVariadic)         OS << "|(1<<TID::Variadic)";
+  if (Inst.hasSideEffects)     OS << "|(1<<TID::UnmodeledSideEffects)";
+  if (Inst.isAsCheapAsAMove)   OS << "|(1<<TID::CheapAsAMove)";
+  if (Inst.hasExtraSrcRegAllocReq) OS << "|(1<<TID::ExtraSrcRegAllocReq)";
+  if (Inst.hasExtraDefRegAllocReq) OS << "|(1<<TID::ExtraDefRegAllocReq)";
+
+  // Emit all of the target-specific flags...
+  BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags");
+  if (!TSF) throw "no TSFlags?";
+  uint64_t Value = 0;
+  for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) {
+    if (BitInit *Bit = dynamic_cast<BitInit*>(TSF->getBit(i)))
+      Value |= uint64_t(Bit->getValue()) << i;
+    else
+      throw "Invalid TSFlags bit in " + Inst.TheDef->getName();
+  }
+  OS << ", 0x";
+  OS.write_hex(Value);
+  OS << "ULL, ";
+
+  // Emit the implicit uses and defs lists...
+  std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses");
+  if (UseList.empty())
+    OS << "NULL, ";
+  else
+    OS << "ImplicitList" << EmittedLists[UseList] << ", ";
+
+  std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs");
+  if (DefList.empty())
+    OS << "NULL, ";
+  else
+    OS << "ImplicitList" << EmittedLists[DefList] << ", ";
+
+  std::map<Record*, unsigned>::iterator BI = BarriersMap.find(Inst.TheDef);
+  if (BI == BarriersMap.end())
+    OS << "NULL, ";
+  else
+    OS << "Barriers" << BI->second << ", ";
+
+  // Emit the operand info.
+  std::vector<std::string> OperandInfo = GetOperandInfo(Inst);
+  if (OperandInfo.empty())
+    OS << "0";
+  else
+    OS << "OperandInfo" << OpInfo.find(OperandInfo)->second;
+
+  OS << " },  // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
+}
diff --git a/src/LLVM/utils/TableGen/InstrInfoEmitter.h b/src/LLVM/utils/TableGen/InstrInfoEmitter.h
new file mode 100644
index 0000000..abb1c6b
--- /dev/null
+++ b/src/LLVM/utils/TableGen/InstrInfoEmitter.h
@@ -0,0 +1,66 @@
+//===- InstrInfoEmitter.h - Generate a Instruction Set Desc. ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend is responsible for emitting a description of the target
+// instruction set for the code generator.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef INSTRINFO_EMITTER_H
+#define INSTRINFO_EMITTER_H
+
+#include "TableGenBackend.h"
+#include "CodeGenDAGPatterns.h"
+#include <vector>
+#include <map>
+
+namespace llvm {
+
+class StringInit;
+class IntInit;
+class ListInit;
+class CodeGenInstruction;
+
+class InstrInfoEmitter : public TableGenBackend {
+  RecordKeeper &Records;
+  CodeGenDAGPatterns CDP;
+  std::map<std::string, unsigned> ItinClassMap;
+  
+public:
+  InstrInfoEmitter(RecordKeeper &R) : Records(R), CDP(R) { }
+
+  // run - Output the instruction set description, returning true on failure.
+  void run(raw_ostream &OS);
+
+private:
+  typedef std::map<std::vector<std::string>, unsigned> OperandInfoMapTy;
+  
+  void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
+                  Record *InstrInfo, 
+                  std::map<std::vector<Record*>, unsigned> &EL,
+                  std::map<Record*, unsigned> &BM,
+                  const OperandInfoMapTy &OpInfo,
+                  raw_ostream &OS);
+
+  // Itinerary information.
+  void GatherItinClasses();
+  unsigned getItinClassNumber(const Record *InstRec);
+  
+  // Operand information.
+  void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs);
+  std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst);
+
+  void DetectRegisterClassBarriers(std::vector<Record*> &Defs,
+                                   const std::vector<CodeGenRegisterClass> &RCs,
+                                   std::vector<Record*> &Barriers);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/utils/TableGen/IntrinsicEmitter.cpp b/src/LLVM/utils/TableGen/IntrinsicEmitter.cpp
new file mode 100644
index 0000000..ba30d97
--- /dev/null
+++ b/src/LLVM/utils/TableGen/IntrinsicEmitter.cpp
@@ -0,0 +1,751 @@
+//===- IntrinsicEmitter.cpp - Generate intrinsic information --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend emits information about intrinsic functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenTarget.h"
+#include "IntrinsicEmitter.h"
+#include "Record.h"
+#include "llvm/ADT/StringExtras.h"
+#include <algorithm>
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// IntrinsicEmitter Implementation
+//===----------------------------------------------------------------------===//
+
+void IntrinsicEmitter::run(raw_ostream &OS) {
+  EmitSourceFileHeader("Intrinsic Function Source Fragment", OS);
+  
+  std::vector<CodeGenIntrinsic> Ints = LoadIntrinsics(Records, TargetOnly);
+  
+  if (TargetOnly && !Ints.empty())
+    TargetPrefix = Ints[0].TargetPrefix;
+
+  EmitPrefix(OS);
+
+  // Emit the enum information.
+  EmitEnumInfo(Ints, OS);
+
+  // Emit the intrinsic ID -> name table.
+  EmitIntrinsicToNameTable(Ints, OS);
+
+  // Emit the intrinsic ID -> overload table.
+  EmitIntrinsicToOverloadTable(Ints, OS);
+
+  // Emit the function name recognizer.
+  EmitFnNameRecognizer(Ints, OS);
+  
+  // Emit the intrinsic verifier.
+  EmitVerifier(Ints, OS);
+  
+  // Emit the intrinsic declaration generator.
+  EmitGenerator(Ints, OS);
+  
+  // Emit the intrinsic parameter attributes.
+  EmitAttributes(Ints, OS);
+
+  // Emit intrinsic alias analysis mod/ref behavior.
+  EmitModRefBehavior(Ints, OS);
+
+  // Emit a list of intrinsics with corresponding GCC builtins.
+  EmitGCCBuiltinList(Ints, OS);
+
+  // Emit code to translate GCC builtins into LLVM intrinsics.
+  EmitIntrinsicToGCCBuiltinMap(Ints, OS);
+
+  EmitSuffix(OS);
+}
+
+void IntrinsicEmitter::EmitPrefix(raw_ostream &OS) {
+  OS << "// VisualStudio defines setjmp as _setjmp\n"
+        "#if defined(_MSC_VER) && defined(setjmp)\n"
+        "#define setjmp_undefined_for_visual_studio\n"
+        "#undef setjmp\n"
+        "#endif\n\n";
+}
+
+void IntrinsicEmitter::EmitSuffix(raw_ostream &OS) {
+  OS << "#if defined(_MSC_VER) && defined(setjmp_undefined_for_visual_studio)\n"
+        "// let's return it to _setjmp state\n"
+        "#define setjmp _setjmp\n"
+        "#endif\n\n";
+}
+
+void IntrinsicEmitter::EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints,
+                                    raw_ostream &OS) {
+  OS << "// Enum values for Intrinsics.h\n";
+  OS << "#ifdef GET_INTRINSIC_ENUM_VALUES\n";
+  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
+    OS << "    " << Ints[i].EnumName;
+    OS << ((i != e-1) ? ", " : "  ");
+    OS << std::string(40-Ints[i].EnumName.size(), ' ') 
+      << "// " << Ints[i].Name << "\n";
+  }
+  OS << "#endif\n\n";
+}
+
+void IntrinsicEmitter::
+EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints, 
+                     raw_ostream &OS) {
+  // Build a function name -> intrinsic name mapping.
+  std::map<std::string, unsigned> IntMapping;
+  for (unsigned i = 0, e = Ints.size(); i != e; ++i)
+    IntMapping[Ints[i].Name] = i;
+    
+  OS << "// Function name -> enum value recognizer code.\n";
+  OS << "#ifdef GET_FUNCTION_RECOGNIZER\n";
+  OS << "  switch (Name[5]) {\n";
+  OS << "  default:\n";
+  // Emit the intrinsics in sorted order.
+  char LastChar = 0;
+  for (std::map<std::string, unsigned>::iterator I = IntMapping.begin(),
+       E = IntMapping.end(); I != E; ++I) {
+    if (I->first[5] != LastChar) {
+      LastChar = I->first[5];
+      OS << "    break;\n";
+      OS << "  case '" << LastChar << "':\n";
+    }
+    
+    // For overloaded intrinsics, only the prefix needs to match
+    if (Ints[I->second].isOverloaded)
+      OS << "    if (Len > " << I->first.size()
+       << " && !memcmp(Name, \"" << I->first << ".\", "
+       << (I->first.size() + 1) << ")) return " << TargetPrefix << "Intrinsic::"
+       << Ints[I->second].EnumName << ";\n";
+    else 
+      OS << "    if (Len == " << I->first.size()
+         << " && !memcmp(Name, \"" << I->first << "\", "
+         << I->first.size() << ")) return " << TargetPrefix << "Intrinsic::"
+         << Ints[I->second].EnumName << ";\n";
+  }
+  OS << "  }\n";
+  OS << "#endif\n\n";
+}
+
+void IntrinsicEmitter::
+EmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints, 
+                         raw_ostream &OS) {
+  OS << "// Intrinsic ID to name table\n";
+  OS << "#ifdef GET_INTRINSIC_NAME_TABLE\n";
+  OS << "  // Note that entry #0 is the invalid intrinsic!\n";
+  for (unsigned i = 0, e = Ints.size(); i != e; ++i)
+    OS << "  \"" << Ints[i].Name << "\",\n";
+  OS << "#endif\n\n";
+}
+
+void IntrinsicEmitter::
+EmitIntrinsicToOverloadTable(const std::vector<CodeGenIntrinsic> &Ints, 
+                         raw_ostream &OS) {
+  OS << "// Intrinsic ID to overload table\n";
+  OS << "#ifdef GET_INTRINSIC_OVERLOAD_TABLE\n";
+  OS << "  // Note that entry #0 is the invalid intrinsic!\n";
+  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
+    OS << "  ";
+    if (Ints[i].isOverloaded)
+      OS << "true";
+    else
+      OS << "false";
+    OS << ",\n";
+  }
+  OS << "#endif\n\n";
+}
+
+static void EmitTypeForValueType(raw_ostream &OS, MVT::SimpleValueType VT) {
+  if (EVT(VT).isInteger()) {
+    unsigned BitWidth = EVT(VT).getSizeInBits();
+    OS << "IntegerType::get(Context, " << BitWidth << ")";
+  } else if (VT == MVT::Other) {
+    // MVT::OtherVT is used to mean the empty struct type here.
+    OS << "StructType::get(Context)";
+  } else if (VT == MVT::f32) {
+    OS << "Type::getFloatTy(Context)";
+  } else if (VT == MVT::f64) {
+    OS << "Type::getDoubleTy(Context)";
+  } else if (VT == MVT::f80) {
+    OS << "Type::getX86_FP80Ty(Context)";
+  } else if (VT == MVT::f128) {
+    OS << "Type::getFP128Ty(Context)";
+  } else if (VT == MVT::ppcf128) {
+    OS << "Type::getPPC_FP128Ty(Context)";
+  } else if (VT == MVT::isVoid) {
+    OS << "Type::getVoidTy(Context)";
+  } else if (VT == MVT::Metadata) {
+    OS << "Type::getMetadataTy(Context)";
+  } else {
+    assert(false && "Unsupported ValueType!");
+  }
+}
+
+static void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType,
+                             unsigned &ArgNo);
+
+static void EmitTypeGenerate(raw_ostream &OS,
+                             const std::vector<Record*> &ArgTypes,
+                             unsigned &ArgNo) {
+  if (ArgTypes.empty())
+    return EmitTypeForValueType(OS, MVT::isVoid);
+  
+  if (ArgTypes.size() == 1)
+    return EmitTypeGenerate(OS, ArgTypes.front(), ArgNo);
+
+  OS << "StructType::get(Context, ";
+
+  for (std::vector<Record*>::const_iterator
+         I = ArgTypes.begin(), E = ArgTypes.end(); I != E; ++I) {
+    EmitTypeGenerate(OS, *I, ArgNo);
+    OS << ", ";
+  }
+
+  OS << " NULL)";
+}
+
+static void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType,
+                             unsigned &ArgNo) {
+  MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT"));
+
+  if (ArgType->isSubClassOf("LLVMMatchType")) {
+    unsigned Number = ArgType->getValueAsInt("Number");
+    assert(Number < ArgNo && "Invalid matching number!");
+    if (ArgType->isSubClassOf("LLVMExtendedElementVectorType"))
+      OS << "VectorType::getExtendedElementVectorType"
+         << "(dyn_cast<VectorType>(Tys[" << Number << "]))";
+    else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType"))
+      OS << "VectorType::getTruncatedElementVectorType"
+         << "(dyn_cast<VectorType>(Tys[" << Number << "]))";
+    else
+      OS << "Tys[" << Number << "]";
+  } else if (VT == MVT::iAny || VT == MVT::fAny || VT == MVT::vAny) {
+    // NOTE: The ArgNo variable here is not the absolute argument number, it is
+    // the index of the "arbitrary" type in the Tys array passed to the
+    // Intrinsic::getDeclaration function. Consequently, we only want to
+    // increment it when we actually hit an overloaded type. Getting this wrong
+    // leads to very subtle bugs!
+    OS << "Tys[" << ArgNo++ << "]";
+  } else if (EVT(VT).isVector()) {
+    EVT VVT = VT;
+    OS << "VectorType::get(";
+    EmitTypeForValueType(OS, VVT.getVectorElementType().getSimpleVT().SimpleTy);
+    OS << ", " << VVT.getVectorNumElements() << ")";
+  } else if (VT == MVT::iPTR) {
+    OS << "PointerType::getUnqual(";
+    EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo);
+    OS << ")";
+  } else if (VT == MVT::iPTRAny) {
+    // Make sure the user has passed us an argument type to overload. If not,
+    // treat it as an ordinary (not overloaded) intrinsic.
+    OS << "(" << ArgNo << " < numTys) ? Tys[" << ArgNo 
+    << "] : PointerType::getUnqual(";
+    EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo);
+    OS << ")";
+    ++ArgNo;
+  } else if (VT == MVT::isVoid) {
+    if (ArgNo == 0)
+      OS << "Type::getVoidTy(Context)";
+    else
+      // MVT::isVoid is used to mean varargs here.
+      OS << "...";
+  } else {
+    EmitTypeForValueType(OS, VT);
+  }
+}
+
+/// RecordListComparator - Provide a deterministic comparator for lists of
+/// records.
+namespace {
+  typedef std::pair<std::vector<Record*>, std::vector<Record*> > RecPair;
+  struct RecordListComparator {
+    bool operator()(const RecPair &LHS,
+                    const RecPair &RHS) const {
+      unsigned i = 0;
+      const std::vector<Record*> *LHSVec = &LHS.first;
+      const std::vector<Record*> *RHSVec = &RHS.first;
+      unsigned RHSSize = RHSVec->size();
+      unsigned LHSSize = LHSVec->size();
+
+      for (; i != LHSSize; ++i) {
+        if (i == RHSSize) return false;  // RHS is shorter than LHS.
+        if ((*LHSVec)[i] != (*RHSVec)[i])
+          return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName();
+      }
+
+      if (i != RHSSize) return true;
+
+      i = 0;
+      LHSVec = &LHS.second;
+      RHSVec = &RHS.second;
+      RHSSize = RHSVec->size();
+      LHSSize = LHSVec->size();
+
+      for (i = 0; i != LHSSize; ++i) {
+        if (i == RHSSize) return false;  // RHS is shorter than LHS.
+        if ((*LHSVec)[i] != (*RHSVec)[i])
+          return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName();
+      }
+
+      return i != RHSSize;
+    }
+  };
+}
+
+void IntrinsicEmitter::EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints, 
+                                    raw_ostream &OS) {
+  OS << "// Verifier::visitIntrinsicFunctionCall code.\n";
+  OS << "#ifdef GET_INTRINSIC_VERIFIER\n";
+  OS << "  switch (ID) {\n";
+  OS << "  default: assert(0 && \"Invalid intrinsic!\");\n";
+  
+  // This checking can emit a lot of very common code.  To reduce the amount of
+  // code that we emit, batch up cases that have identical types.  This avoids
+  // problems where GCC can run out of memory compiling Verifier.cpp.
+  typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy;
+  MapTy UniqueArgInfos;
+  
+  // Compute the unique argument type info.
+  for (unsigned i = 0, e = Ints.size(); i != e; ++i)
+    UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs,
+                             Ints[i].IS.ParamTypeDefs)].push_back(i);
+
+  // Loop through the array, emitting one comparison for each batch.
+  for (MapTy::iterator I = UniqueArgInfos.begin(),
+       E = UniqueArgInfos.end(); I != E; ++I) {
+    for (unsigned i = 0, e = I->second.size(); i != e; ++i)
+      OS << "  case Intrinsic::" << Ints[I->second[i]].EnumName << ":\t\t// "
+         << Ints[I->second[i]].Name << "\n";
+    
+    const RecPair &ArgTypes = I->first;
+    const std::vector<Record*> &RetTys = ArgTypes.first;
+    const std::vector<Record*> &ParamTys = ArgTypes.second;
+    std::vector<unsigned> OverloadedTypeIndices;
+
+    OS << "    VerifyIntrinsicPrototype(ID, IF, " << RetTys.size() << ", "
+       << ParamTys.size();
+
+    // Emit return types.
+    for (unsigned j = 0, je = RetTys.size(); j != je; ++j) {
+      Record *ArgType = RetTys[j];
+      OS << ", ";
+
+      if (ArgType->isSubClassOf("LLVMMatchType")) {
+        unsigned Number = ArgType->getValueAsInt("Number");
+        assert(Number < OverloadedTypeIndices.size() &&
+               "Invalid matching number!");
+        Number = OverloadedTypeIndices[Number];
+        if (ArgType->isSubClassOf("LLVMExtendedElementVectorType"))
+          OS << "~(ExtendedElementVectorType | " << Number << ")";
+        else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType"))
+          OS << "~(TruncatedElementVectorType | " << Number << ")";
+        else
+          OS << "~" << Number;
+      } else {
+        MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT"));
+        OS << getEnumName(VT);
+
+        if (EVT(VT).isOverloaded())
+          OverloadedTypeIndices.push_back(j);
+
+        if (VT == MVT::isVoid && j != 0 && j != je - 1)
+          throw "Var arg type not last argument";
+      }
+    }
+
+    // Emit the parameter types.
+    for (unsigned j = 0, je = ParamTys.size(); j != je; ++j) {
+      Record *ArgType = ParamTys[j];
+      OS << ", ";
+
+      if (ArgType->isSubClassOf("LLVMMatchType")) {
+        unsigned Number = ArgType->getValueAsInt("Number");
+        assert(Number < OverloadedTypeIndices.size() &&
+               "Invalid matching number!");
+        Number = OverloadedTypeIndices[Number];
+        if (ArgType->isSubClassOf("LLVMExtendedElementVectorType"))
+          OS << "~(ExtendedElementVectorType | " << Number << ")";
+        else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType"))
+          OS << "~(TruncatedElementVectorType | " << Number << ")";
+        else
+          OS << "~" << Number;
+      } else {
+        MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT"));
+        OS << getEnumName(VT);
+
+        if (EVT(VT).isOverloaded())
+          OverloadedTypeIndices.push_back(j + RetTys.size());
+
+        if (VT == MVT::isVoid && j != 0 && j != je - 1)
+          throw "Var arg type not last argument";
+      }
+    }
+      
+    OS << ");\n";
+    OS << "    break;\n";
+  }
+  OS << "  }\n";
+  OS << "#endif\n\n";
+}
+
+void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, 
+                                     raw_ostream &OS) {
+  OS << "// Code for generating Intrinsic function declarations.\n";
+  OS << "#ifdef GET_INTRINSIC_GENERATOR\n";
+  OS << "  switch (id) {\n";
+  OS << "  default: assert(0 && \"Invalid intrinsic!\");\n";
+  
+  // Similar to GET_INTRINSIC_VERIFIER, batch up cases that have identical
+  // types.
+  typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy;
+  MapTy UniqueArgInfos;
+  
+  // Compute the unique argument type info.
+  for (unsigned i = 0, e = Ints.size(); i != e; ++i)
+    UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs,
+                             Ints[i].IS.ParamTypeDefs)].push_back(i);
+
+  // Loop through the array, emitting one generator for each batch.
+  std::string IntrinsicStr = TargetPrefix + "Intrinsic::";
+  
+  for (MapTy::iterator I = UniqueArgInfos.begin(),
+       E = UniqueArgInfos.end(); I != E; ++I) {
+    for (unsigned i = 0, e = I->second.size(); i != e; ++i)
+      OS << "  case " << IntrinsicStr << Ints[I->second[i]].EnumName 
+         << ":\t\t// " << Ints[I->second[i]].Name << "\n";
+    
+    const RecPair &ArgTypes = I->first;
+    const std::vector<Record*> &RetTys = ArgTypes.first;
+    const std::vector<Record*> &ParamTys = ArgTypes.second;
+
+    unsigned N = ParamTys.size();
+
+    if (N > 1 &&
+        getValueType(ParamTys[N - 1]->getValueAsDef("VT")) == MVT::isVoid) {
+      OS << "    IsVarArg = true;\n";
+      --N;
+    }
+
+    unsigned ArgNo = 0;
+    OS << "    ResultTy = ";
+    EmitTypeGenerate(OS, RetTys, ArgNo);
+    OS << ";\n";
+    
+    for (unsigned j = 0; j != N; ++j) {
+      OS << "    ArgTys.push_back(";
+      EmitTypeGenerate(OS, ParamTys[j], ArgNo);
+      OS << ");\n";
+    }
+
+    OS << "    break;\n";
+  }
+
+  OS << "  }\n";
+  OS << "#endif\n\n";
+}
+
+/// EmitAttributes - This emits the Intrinsic::getAttributes method.
+void IntrinsicEmitter::
+EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
+  OS << "// Add parameter attributes that are not common to all intrinsics.\n";
+  OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n";
+  if (TargetOnly)
+    OS << "static AttrListPtr getAttributes(" << TargetPrefix 
+       << "Intrinsic::ID id) {";
+  else
+    OS << "AttrListPtr Intrinsic::getAttributes(ID id) {";
+  OS << "  // No intrinsic can throw exceptions.\n";
+  OS << "  Attributes Attr = Attribute::NoUnwind;\n";
+  OS << "  switch (id) {\n";
+  OS << "  default: break;\n";
+  unsigned MaxArgAttrs = 0;
+  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
+    MaxArgAttrs =
+      std::max(MaxArgAttrs, unsigned(Ints[i].ArgumentAttributes.size()));
+    switch (Ints[i].ModRef) {
+    default: break;
+    case CodeGenIntrinsic::NoMem:
+      OS << "  case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 
+         << ":\n";
+      break;
+    }
+  }
+  OS << "    Attr |= Attribute::ReadNone; // These do not access memory.\n";
+  OS << "    break;\n";
+  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
+    switch (Ints[i].ModRef) {
+    default: break;
+    case CodeGenIntrinsic::ReadArgMem:
+    case CodeGenIntrinsic::ReadMem:
+      OS << "  case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 
+         << ":\n";
+      break;
+    }
+  }
+  OS << "    Attr |= Attribute::ReadOnly; // These do not write memory.\n";
+  OS << "    break;\n";
+  OS << "  }\n";
+  OS << "  AttributeWithIndex AWI[" << MaxArgAttrs+1 << "];\n";
+  OS << "  unsigned NumAttrs = 0;\n";
+  OS << "  switch (id) {\n";
+  OS << "  default: break;\n";
+  
+  // Add argument attributes for any intrinsics that have them.
+  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
+    if (Ints[i].ArgumentAttributes.empty()) continue;
+    
+    OS << "  case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 
+       << ":\n";
+
+    std::vector<std::pair<unsigned, CodeGenIntrinsic::ArgAttribute> > ArgAttrs =
+      Ints[i].ArgumentAttributes;
+    // Sort by argument index.
+    std::sort(ArgAttrs.begin(), ArgAttrs.end());
+
+    unsigned NumArgsWithAttrs = 0;
+
+    while (!ArgAttrs.empty()) {
+      unsigned ArgNo = ArgAttrs[0].first;
+      
+      OS << "    AWI[" << NumArgsWithAttrs++ << "] = AttributeWithIndex::get("
+         << ArgNo+1 << ", 0";
+
+      while (!ArgAttrs.empty() && ArgAttrs[0].first == ArgNo) {
+        switch (ArgAttrs[0].second) {
+        default: assert(0 && "Unknown arg attribute");
+        case CodeGenIntrinsic::NoCapture:
+          OS << "|Attribute::NoCapture";
+          break;
+        }
+        ArgAttrs.erase(ArgAttrs.begin());
+      }
+      OS << ");\n";
+    }
+    
+    OS << "    NumAttrs = " << NumArgsWithAttrs << ";\n";
+    OS << "    break;\n";
+  }
+  
+  OS << "  }\n";
+  OS << "  AWI[NumAttrs] = AttributeWithIndex::get(~0, Attr);\n";
+  OS << "  return AttrListPtr::get(AWI, NumAttrs+1);\n";
+  OS << "}\n";
+  OS << "#endif // GET_INTRINSIC_ATTRIBUTES\n\n";
+}
+
+/// EmitModRefBehavior - Determine intrinsic alias analysis mod/ref behavior.
+void IntrinsicEmitter::
+EmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){
+  OS << "// Determine intrinsic alias analysis mod/ref behavior.\n";
+  OS << "#ifdef GET_INTRINSIC_MODREF_BEHAVIOR\n";
+  OS << "switch (iid) {\n";
+  OS << "default:\n    return UnknownModRefBehavior;\n";
+  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
+    if (Ints[i].ModRef == CodeGenIntrinsic::ReadWriteMem)
+      continue;
+    OS << "case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName
+      << ":\n";
+    switch (Ints[i].ModRef) {
+    default:
+      assert(false && "Unknown Mod/Ref type!");
+    case CodeGenIntrinsic::NoMem:
+      OS << "  return DoesNotAccessMemory;\n";
+      break;
+    case CodeGenIntrinsic::ReadArgMem:
+    case CodeGenIntrinsic::ReadMem:
+      OS << "  return OnlyReadsMemory;\n";
+      break;
+    case CodeGenIntrinsic::ReadWriteArgMem:
+      OS << "  return AccessesArguments;\n";
+      break;
+    }
+  }
+  OS << "}\n";
+  OS << "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n";
+}
+
+void IntrinsicEmitter::
+EmitGCCBuiltinList(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){
+  OS << "// Get the GCC builtin that corresponds to an LLVM intrinsic.\n";
+  OS << "#ifdef GET_GCC_BUILTIN_NAME\n";
+  OS << "  switch (F->getIntrinsicID()) {\n";
+  OS << "  default: BuiltinName = \"\"; break;\n";
+  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
+    if (!Ints[i].GCCBuiltinName.empty()) {
+      OS << "  case Intrinsic::" << Ints[i].EnumName << ": BuiltinName = \""
+         << Ints[i].GCCBuiltinName << "\"; break;\n";
+    }
+  }
+  OS << "  }\n";
+  OS << "#endif\n\n";
+}
+
+/// EmitBuiltinComparisons - Emit comparisons to determine whether the specified
+/// sorted range of builtin names is equal to the current builtin.  This breaks
+/// it down into a simple tree.
+///
+/// At this point, we know that all the builtins in the range have the same name
+/// for the first 'CharStart' characters.  Only the end of the name needs to be
+/// discriminated.
+typedef std::map<std::string, std::string>::const_iterator StrMapIterator;
+static void EmitBuiltinComparisons(StrMapIterator Start, StrMapIterator End,
+                                   unsigned CharStart, unsigned Indent,
+                                   std::string TargetPrefix, raw_ostream &OS) {
+  if (Start == End) return; // empty range.
+  
+  // Determine what, if anything, is the same about all these strings.
+  std::string CommonString = Start->first;
+  unsigned NumInRange = 0;
+  for (StrMapIterator I = Start; I != End; ++I, ++NumInRange) {
+    // Find the first character that doesn't match.
+    const std::string &ThisStr = I->first;
+    unsigned NonMatchChar = CharStart;
+    while (NonMatchChar < CommonString.size() && 
+           NonMatchChar < ThisStr.size() &&
+           CommonString[NonMatchChar] == ThisStr[NonMatchChar])
+      ++NonMatchChar;
+    // Truncate off pieces that don't match.
+    CommonString.resize(NonMatchChar);
+  }
+  
+  // Just compare the rest of the string.
+  if (NumInRange == 1) {
+    if (CharStart != CommonString.size()) {
+      OS << std::string(Indent*2, ' ') << "if (!memcmp(BuiltinName";
+      if (CharStart) OS << "+" << CharStart;
+      OS << ", \"" << (CommonString.c_str()+CharStart) << "\", ";
+      OS << CommonString.size() - CharStart << "))\n";
+      ++Indent;
+    }
+    OS << std::string(Indent*2, ' ') << "IntrinsicID = " << TargetPrefix
+       << "Intrinsic::";
+    OS << Start->second << ";\n";
+    return;
+  }
+
+  // At this point, we potentially have a common prefix for these builtins, emit
+  // a check for this common prefix.
+  if (CommonString.size() != CharStart) {
+    OS << std::string(Indent*2, ' ') << "if (!memcmp(BuiltinName";
+    if (CharStart) OS << "+" << CharStart;
+    OS << ", \"" << (CommonString.c_str()+CharStart) << "\", ";
+    OS << CommonString.size()-CharStart << ")) {\n";
+    
+    EmitBuiltinComparisons(Start, End, CommonString.size(), Indent+1, 
+                           TargetPrefix, OS);
+    OS << std::string(Indent*2, ' ') << "}\n";
+    return;
+  }
+  
+  // Output a switch on the character that differs across the set.
+  OS << std::string(Indent*2, ' ') << "switch (BuiltinName[" << CharStart
+      << "]) {";
+  if (CharStart)
+    OS << "  // \"" << std::string(Start->first.begin(), 
+                                   Start->first.begin()+CharStart) << "\"";
+  OS << "\n";
+  
+  for (StrMapIterator I = Start; I != End; ) {
+    char ThisChar = I->first[CharStart];
+    OS << std::string(Indent*2, ' ') << "case '" << ThisChar << "':\n";
+    // Figure out the range that has this common character.
+    StrMapIterator NextChar = I;
+    for (++NextChar; NextChar != End && NextChar->first[CharStart] == ThisChar;
+         ++NextChar)
+      /*empty*/;
+    EmitBuiltinComparisons(I, NextChar, CharStart+1, Indent+1, TargetPrefix,OS);
+    OS << std::string(Indent*2, ' ') << "  break;\n";
+    I = NextChar;
+  }
+  OS << std::string(Indent*2, ' ') << "}\n";
+}
+
+/// EmitTargetBuiltins - All of the builtins in the specified map are for the
+/// same target, and we already checked it.
+static void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM,
+                               const std::string &TargetPrefix,
+                               raw_ostream &OS) {
+  // Rearrange the builtins by length.
+  std::vector<std::map<std::string, std::string> > BuiltinsByLen;
+  BuiltinsByLen.reserve(100);
+  
+  for (StrMapIterator I = BIM.begin(), E = BIM.end(); I != E; ++I) {
+    if (I->first.size() >= BuiltinsByLen.size())
+      BuiltinsByLen.resize(I->first.size()+1);
+    BuiltinsByLen[I->first.size()].insert(*I);
+  }
+  
+  // Now that we have all the builtins by their length, emit a switch stmt.
+  OS << "    switch (strlen(BuiltinName)) {\n";
+  OS << "    default: break;\n";
+  for (unsigned i = 0, e = BuiltinsByLen.size(); i != e; ++i) {
+    if (BuiltinsByLen[i].empty()) continue;
+    OS << "    case " << i << ":\n";
+    EmitBuiltinComparisons(BuiltinsByLen[i].begin(), BuiltinsByLen[i].end(),
+                           0, 3, TargetPrefix, OS);
+    OS << "      break;\n";
+  }
+  OS << "    }\n";
+}
+
+        
+void IntrinsicEmitter::
+EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, 
+                             raw_ostream &OS) {
+  typedef std::map<std::string, std::map<std::string, std::string> > BIMTy;
+  BIMTy BuiltinMap;
+  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
+    if (!Ints[i].GCCBuiltinName.empty()) {
+      // Get the map for this target prefix.
+      std::map<std::string, std::string> &BIM =BuiltinMap[Ints[i].TargetPrefix];
+      
+      if (!BIM.insert(std::make_pair(Ints[i].GCCBuiltinName,
+                                     Ints[i].EnumName)).second)
+        throw "Intrinsic '" + Ints[i].TheDef->getName() +
+              "': duplicate GCC builtin name!";
+    }
+  }
+  
+  OS << "// Get the LLVM intrinsic that corresponds to a GCC builtin.\n";
+  OS << "// This is used by the C front-end.  The GCC builtin name is passed\n";
+  OS << "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n";
+  OS << "// in as TargetPrefix.  The result is assigned to 'IntrinsicID'.\n";
+  OS << "#ifdef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN\n";
+  
+  if (TargetOnly) {
+    OS << "static " << TargetPrefix << "Intrinsic::ID "
+       << "getIntrinsicForGCCBuiltin(const char "
+       << "*TargetPrefix, const char *BuiltinName) {\n";
+    OS << "  " << TargetPrefix << "Intrinsic::ID IntrinsicID = ";
+  } else {
+    OS << "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char "
+       << "*TargetPrefix, const char *BuiltinName) {\n";
+    OS << "  Intrinsic::ID IntrinsicID = ";
+  }
+  
+  if (TargetOnly)
+    OS << "(" << TargetPrefix<< "Intrinsic::ID)";
+
+  OS << "Intrinsic::not_intrinsic;\n";
+  
+  // Note: this could emit significantly better code if we cared.
+  for (BIMTy::iterator I = BuiltinMap.begin(), E = BuiltinMap.end();I != E;++I){
+    OS << "  ";
+    if (!I->first.empty())
+      OS << "if (!strcmp(TargetPrefix, \"" << I->first << "\")) ";
+    else
+      OS << "/* Target Independent Builtins */ ";
+    OS << "{\n";
+
+    // Emit the comparisons for this target prefix.
+    EmitTargetBuiltins(I->second, TargetPrefix, OS);
+    OS << "  }\n";
+  }
+  OS << "  return IntrinsicID;\n";
+  OS << "}\n";
+  OS << "#endif\n\n";
+}
diff --git a/src/LLVM/utils/TableGen/IntrinsicEmitter.h b/src/LLVM/utils/TableGen/IntrinsicEmitter.h
new file mode 100644
index 0000000..b1efecb
--- /dev/null
+++ b/src/LLVM/utils/TableGen/IntrinsicEmitter.h
@@ -0,0 +1,63 @@
+//===- IntrinsicEmitter.h - Generate intrinsic information ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend emits information about intrinsic functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef INTRINSIC_EMITTER_H
+#define INTRINSIC_EMITTER_H
+
+#include "CodeGenIntrinsics.h"
+#include "TableGenBackend.h"
+
+namespace llvm {
+  class IntrinsicEmitter : public TableGenBackend {
+    RecordKeeper &Records;
+    bool TargetOnly;
+    std::string TargetPrefix;
+    
+  public:
+    IntrinsicEmitter(RecordKeeper &R, bool T = false) 
+      : Records(R), TargetOnly(T) {}
+
+    void run(raw_ostream &OS);
+
+    void EmitPrefix(raw_ostream &OS);
+    
+    void EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints, 
+                      raw_ostream &OS);
+
+    void EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints, 
+                              raw_ostream &OS);
+    void EmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints, 
+                                  raw_ostream &OS);
+    void EmitIntrinsicToOverloadTable(const std::vector<CodeGenIntrinsic> &Ints, 
+                                      raw_ostream &OS);
+    void EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints, 
+                      raw_ostream &OS);
+    void EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, 
+                       raw_ostream &OS);
+    void EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints,
+                        raw_ostream &OS);
+    void EmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints,
+                            raw_ostream &OS);
+    void EmitGCCBuiltinList(const std::vector<CodeGenIntrinsic> &Ints, 
+                            raw_ostream &OS);
+    void EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, 
+                                      raw_ostream &OS);
+    void EmitSuffix(raw_ostream &OS);
+  };
+
+} // End llvm namespace
+
+#endif
+
+
+
diff --git a/src/LLVM/utils/TableGen/LLVMCConfigurationEmitter.cpp b/src/LLVM/utils/TableGen/LLVMCConfigurationEmitter.cpp
new file mode 100644
index 0000000..d4624e2
--- /dev/null
+++ b/src/LLVM/utils/TableGen/LLVMCConfigurationEmitter.cpp
@@ -0,0 +1,3153 @@
+//===- LLVMCConfigurationEmitter.cpp - Generate LLVMC config ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open
+// Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend is responsible for emitting LLVMC configuration code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LLVMCConfigurationEmitter.h"
+#include "Record.h"
+
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringSet.h"
+
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <stdexcept>
+#include <string>
+#include <typeinfo>
+
+using namespace llvm;
+
+namespace {
+
+//===----------------------------------------------------------------------===//
+/// Typedefs
+
+typedef std::vector<Record*> RecordVector;
+typedef std::vector<std::string> StrVector;
+
+//===----------------------------------------------------------------------===//
+/// Constants
+
+// Indentation.
+const unsigned TabWidth = 4;
+const unsigned Indent1  = TabWidth*1;
+const unsigned Indent2  = TabWidth*2;
+const unsigned Indent3  = TabWidth*3;
+const unsigned Indent4  = TabWidth*4;
+
+// Default help string.
+const char * const DefaultHelpString = "NO HELP MESSAGE PROVIDED";
+
+// Name for the "sink" option.
+const char * const SinkOptionName = "AutoGeneratedSinkOption";
+
+//===----------------------------------------------------------------------===//
+/// Helper functions
+
+/// Id - An 'identity' function object.
+struct Id {
+  template<typename T0>
+  void operator()(const T0&) const {
+  }
+  template<typename T0, typename T1>
+  void operator()(const T0&, const T1&) const {
+  }
+  template<typename T0, typename T1, typename T2>
+  void operator()(const T0&, const T1&, const T2&) const {
+  }
+};
+
+int InitPtrToInt(const Init* ptr) {
+  const IntInit& val = dynamic_cast<const IntInit&>(*ptr);
+  return val.getValue();
+}
+
+const std::string& InitPtrToString(const Init* ptr) {
+  const StringInit& val = dynamic_cast<const StringInit&>(*ptr);
+  return val.getValue();
+}
+
+const ListInit& InitPtrToList(const Init* ptr) {
+  const ListInit& val = dynamic_cast<const ListInit&>(*ptr);
+  return val;
+}
+
+const DagInit& InitPtrToDag(const Init* ptr) {
+  const DagInit& val = dynamic_cast<const DagInit&>(*ptr);
+  return val;
+}
+
+const std::string GetOperatorName(const DagInit& D) {
+  return D.getOperator()->getAsString();
+}
+
+/// CheckBooleanConstant - Check that the provided value is a boolean constant.
+void CheckBooleanConstant(const Init* I) {
+  const DefInit& val = dynamic_cast<const DefInit&>(*I);
+  const std::string& str = val.getAsString();
+
+  if (str != "true" && str != "false") {
+    throw "Incorrect boolean value: '" + str +
+      "': must be either 'true' or 'false'";
+  }
+}
+
+// CheckNumberOfArguments - Ensure that the number of args in d is
+// greater than or equal to min_arguments, otherwise throw an exception.
+void CheckNumberOfArguments (const DagInit& d, unsigned minArgs) {
+  if (d.getNumArgs() < minArgs)
+    throw GetOperatorName(d) + ": too few arguments!";
+}
+
+// IsDagEmpty - is this DAG marked with an empty marker?
+bool IsDagEmpty (const DagInit& d) {
+  return GetOperatorName(d) == "empty_dag_marker";
+}
+
+// EscapeVariableName - Escape commas and other symbols not allowed
+// in the C++ variable names. Makes it possible to use options named
+// like "Wa," (useful for prefix options).
+std::string EscapeVariableName (const std::string& Var) {
+  std::string ret;
+  for (unsigned i = 0; i != Var.size(); ++i) {
+    char cur_char = Var[i];
+    if (cur_char == ',') {
+      ret += "_comma_";
+    }
+    else if (cur_char == '+') {
+      ret += "_plus_";
+    }
+    else if (cur_char == '-') {
+      ret += "_dash_";
+    }
+    else {
+      ret.push_back(cur_char);
+    }
+  }
+  return ret;
+}
+
+/// EscapeQuotes - Replace '"' with '\"'.
+std::string EscapeQuotes (const std::string& Var) {
+  std::string ret;
+  for (unsigned i = 0; i != Var.size(); ++i) {
+    char cur_char = Var[i];
+    if (cur_char == '"') {
+      ret += "\\\"";
+    }
+    else {
+      ret.push_back(cur_char);
+    }
+  }
+  return ret;
+}
+
+/// OneOf - Does the input string contain this character?
+bool OneOf(const char* lst, char c) {
+  while (*lst) {
+    if (*lst++ == c)
+      return true;
+  }
+  return false;
+}
+
+template <class I, class S>
+void CheckedIncrement(I& P, I E, S ErrorString) {
+  ++P;
+  if (P == E)
+    throw ErrorString;
+}
+
+// apply is needed because C++'s syntax doesn't let us construct a function
+// object and call it in the same statement.
+template<typename F, typename T0>
+void apply(F Fun, T0& Arg0) {
+  return Fun(Arg0);
+}
+
+template<typename F, typename T0, typename T1>
+void apply(F Fun, T0& Arg0, T1& Arg1) {
+  return Fun(Arg0, Arg1);
+}
+
+//===----------------------------------------------------------------------===//
+/// Back-end specific code
+
+
+/// OptionType - One of six different option types. See the
+/// documentation for detailed description of differences.
+namespace OptionType {
+
+  enum OptionType { Alias, Switch, SwitchList,
+                    Parameter, ParameterList, Prefix, PrefixList };
+
+  bool IsAlias(OptionType t) {
+    return (t == Alias);
+  }
+
+  bool IsList (OptionType t) {
+    return (t == SwitchList || t == ParameterList || t == PrefixList);
+  }
+
+  bool IsSwitch (OptionType t) {
+    return (t == Switch);
+  }
+
+  bool IsSwitchList (OptionType t) {
+    return (t == SwitchList);
+  }
+
+  bool IsParameter (OptionType t) {
+    return (t == Parameter || t == Prefix);
+  }
+
+}
+
+OptionType::OptionType stringToOptionType(const std::string& T) {
+  if (T == "alias_option")
+    return OptionType::Alias;
+  else if (T == "switch_option")
+    return OptionType::Switch;
+  else if (T == "switch_list_option")
+    return OptionType::SwitchList;
+  else if (T == "parameter_option")
+    return OptionType::Parameter;
+  else if (T == "parameter_list_option")
+    return OptionType::ParameterList;
+  else if (T == "prefix_option")
+    return OptionType::Prefix;
+  else if (T == "prefix_list_option")
+    return OptionType::PrefixList;
+  else
+    throw "Unknown option type: " + T + '!';
+}
+
+namespace OptionDescriptionFlags {
+  enum OptionDescriptionFlags { Required = 0x1, Hidden = 0x2,
+                                ReallyHidden = 0x4, Extern = 0x8,
+                                OneOrMore = 0x10, Optional = 0x20,
+                                CommaSeparated = 0x40, ForwardNotSplit = 0x80,
+                                ZeroOrMore = 0x100 };
+}
+
+/// OptionDescription - Represents data contained in a single
+/// OptionList entry.
+struct OptionDescription {
+  OptionType::OptionType Type;
+  std::string Name;
+  unsigned Flags;
+  std::string Help;
+  unsigned MultiVal;
+  Init* InitVal;
+
+  OptionDescription(OptionType::OptionType t = OptionType::Switch,
+                    const std::string& n = "",
+                    const std::string& h = DefaultHelpString)
+    : Type(t), Name(n), Flags(0x0), Help(h), MultiVal(1), InitVal(0)
+  {}
+
+  /// GenTypeDeclaration - Returns the C++ variable type of this
+  /// option.
+  const char* GenTypeDeclaration() const;
+
+  /// GenVariableName - Returns the variable name used in the
+  /// generated C++ code.
+  std::string GenVariableName() const;
+
+  /// Merge - Merge two option descriptions.
+  void Merge (const OptionDescription& other);
+
+  /// CheckConsistency - Check that the flags are consistent.
+  void CheckConsistency() const;
+
+  // Misc convenient getters/setters.
+
+  bool isAlias() const;
+
+  bool isMultiVal() const;
+
+  bool isCommaSeparated() const;
+  void setCommaSeparated();
+
+  bool isExtern() const;
+  void setExtern();
+
+  bool isForwardNotSplit() const;
+  void setForwardNotSplit();
+
+  bool isRequired() const;
+  void setRequired();
+
+  bool isOneOrMore() const;
+  void setOneOrMore();
+
+  bool isZeroOrMore() const;
+  void setZeroOrMore();
+
+  bool isOptional() const;
+  void setOptional();
+
+  bool isHidden() const;
+  void setHidden();
+
+  bool isReallyHidden() const;
+  void setReallyHidden();
+
+  bool isSwitch() const
+  { return OptionType::IsSwitch(this->Type); }
+
+  bool isSwitchList() const
+  { return OptionType::IsSwitchList(this->Type); }
+
+  bool isParameter() const
+  { return OptionType::IsParameter(this->Type); }
+
+  bool isList() const
+  { return OptionType::IsList(this->Type); }
+
+  bool isParameterList() const
+  { return (OptionType::IsList(this->Type)
+            && !OptionType::IsSwitchList(this->Type)); }
+
+};
+
+void OptionDescription::CheckConsistency() const {
+  unsigned i = 0;
+
+  i += this->isRequired();
+  i += this->isOptional();
+  i += this->isOneOrMore();
+  i += this->isZeroOrMore();
+
+  if (i > 1) {
+    throw "Only one of (required), (optional), (one_or_more) or "
+      "(zero_or_more) properties is allowed!";
+  }
+}
+
+void OptionDescription::Merge (const OptionDescription& other)
+{
+  if (other.Type != Type)
+    throw "Conflicting definitions for the option " + Name + "!";
+
+  if (Help == other.Help || Help == DefaultHelpString)
+    Help = other.Help;
+  else if (other.Help != DefaultHelpString) {
+    llvm::errs() << "Warning: several different help strings"
+      " defined for option " + Name + "\n";
+  }
+
+  Flags |= other.Flags;
+}
+
+bool OptionDescription::isAlias() const {
+  return OptionType::IsAlias(this->Type);
+}
+
+bool OptionDescription::isMultiVal() const {
+  return MultiVal > 1;
+}
+
+bool OptionDescription::isCommaSeparated() const {
+  return Flags & OptionDescriptionFlags::CommaSeparated;
+}
+void OptionDescription::setCommaSeparated() {
+  Flags |= OptionDescriptionFlags::CommaSeparated;
+}
+
+bool OptionDescription::isForwardNotSplit() const {
+  return Flags & OptionDescriptionFlags::ForwardNotSplit;
+}
+void OptionDescription::setForwardNotSplit() {
+  Flags |= OptionDescriptionFlags::ForwardNotSplit;
+}
+
+bool OptionDescription::isExtern() const {
+  return Flags & OptionDescriptionFlags::Extern;
+}
+void OptionDescription::setExtern() {
+  Flags |= OptionDescriptionFlags::Extern;
+}
+
+bool OptionDescription::isRequired() const {
+  return Flags & OptionDescriptionFlags::Required;
+}
+void OptionDescription::setRequired() {
+  Flags |= OptionDescriptionFlags::Required;
+}
+
+bool OptionDescription::isOneOrMore() const {
+  return Flags & OptionDescriptionFlags::OneOrMore;
+}
+void OptionDescription::setOneOrMore() {
+  Flags |= OptionDescriptionFlags::OneOrMore;
+}
+
+bool OptionDescription::isZeroOrMore() const {
+  return Flags & OptionDescriptionFlags::ZeroOrMore;
+}
+void OptionDescription::setZeroOrMore() {
+  Flags |= OptionDescriptionFlags::ZeroOrMore;
+}
+
+bool OptionDescription::isOptional() const {
+  return Flags & OptionDescriptionFlags::Optional;
+}
+void OptionDescription::setOptional() {
+  Flags |= OptionDescriptionFlags::Optional;
+}
+
+bool OptionDescription::isHidden() const {
+  return Flags & OptionDescriptionFlags::Hidden;
+}
+void OptionDescription::setHidden() {
+  Flags |= OptionDescriptionFlags::Hidden;
+}
+
+bool OptionDescription::isReallyHidden() const {
+  return Flags & OptionDescriptionFlags::ReallyHidden;
+}
+void OptionDescription::setReallyHidden() {
+  Flags |= OptionDescriptionFlags::ReallyHidden;
+}
+
+const char* OptionDescription::GenTypeDeclaration() const {
+  switch (Type) {
+  case OptionType::Alias:
+    return "cl::alias";
+  case OptionType::PrefixList:
+  case OptionType::ParameterList:
+    return "cl::list<std::string>";
+  case OptionType::Switch:
+    return "cl::opt<bool>";
+  case OptionType::SwitchList:
+    return "cl::list<bool>";
+  case OptionType::Parameter:
+  case OptionType::Prefix:
+  default:
+    return "cl::opt<std::string>";
+  }
+}
+
+std::string OptionDescription::GenVariableName() const {
+  const std::string& EscapedName = EscapeVariableName(Name);
+  switch (Type) {
+  case OptionType::Alias:
+    return "AutoGeneratedAlias_" + EscapedName;
+  case OptionType::PrefixList:
+  case OptionType::ParameterList:
+    return "AutoGeneratedList_" + EscapedName;
+  case OptionType::Switch:
+    return "AutoGeneratedSwitch_" + EscapedName;
+  case OptionType::SwitchList:
+    return "AutoGeneratedSwitchList_" + EscapedName;
+  case OptionType::Prefix:
+  case OptionType::Parameter:
+  default:
+    return "AutoGeneratedParameter_" + EscapedName;
+  }
+}
+
+/// OptionDescriptions - An OptionDescription array plus some helper
+/// functions.
+class OptionDescriptions {
+  typedef StringMap<OptionDescription> container_type;
+
+  /// Descriptions - A list of OptionDescriptions.
+  container_type Descriptions;
+
+public:
+  /// FindOption - exception-throwing wrapper for find().
+  const OptionDescription& FindOption(const std::string& OptName) const;
+
+  // Wrappers for FindOption that throw an exception in case the option has a
+  // wrong type.
+  const OptionDescription& FindSwitch(const std::string& OptName) const;
+  const OptionDescription& FindParameter(const std::string& OptName) const;
+  const OptionDescription& FindList(const std::string& OptName) const;
+  const OptionDescription& FindParameterList(const std::string& OptName) const;
+  const OptionDescription&
+  FindListOrParameter(const std::string& OptName) const;
+  const OptionDescription&
+  FindParameterListOrParameter(const std::string& OptName) const;
+
+  /// insertDescription - Insert new OptionDescription into
+  /// OptionDescriptions list
+  void InsertDescription (const OptionDescription& o);
+
+  // Support for STL-style iteration
+  typedef container_type::const_iterator const_iterator;
+  const_iterator begin() const { return Descriptions.begin(); }
+  const_iterator end() const { return Descriptions.end(); }
+};
+
+const OptionDescription&
+OptionDescriptions::FindOption(const std::string& OptName) const {
+  const_iterator I = Descriptions.find(OptName);
+  if (I != Descriptions.end())
+    return I->second;
+  else
+    throw OptName + ": no such option!";
+}
+
+const OptionDescription&
+OptionDescriptions::FindSwitch(const std::string& OptName) const {
+  const OptionDescription& OptDesc = this->FindOption(OptName);
+  if (!OptDesc.isSwitch())
+    throw OptName + ": incorrect option type - should be a switch!";
+  return OptDesc;
+}
+
+const OptionDescription&
+OptionDescriptions::FindList(const std::string& OptName) const {
+  const OptionDescription& OptDesc = this->FindOption(OptName);
+  if (!OptDesc.isList())
+    throw OptName + ": incorrect option type - should be a list!";
+  return OptDesc;
+}
+
+const OptionDescription&
+OptionDescriptions::FindParameterList(const std::string& OptName) const {
+  const OptionDescription& OptDesc = this->FindOption(OptName);
+  if (!OptDesc.isList() || OptDesc.isSwitchList())
+    throw OptName + ": incorrect option type - should be a parameter list!";
+  return OptDesc;
+}
+
+const OptionDescription&
+OptionDescriptions::FindParameter(const std::string& OptName) const {
+  const OptionDescription& OptDesc = this->FindOption(OptName);
+  if (!OptDesc.isParameter())
+    throw OptName + ": incorrect option type - should be a parameter!";
+  return OptDesc;
+}
+
+const OptionDescription&
+OptionDescriptions::FindListOrParameter(const std::string& OptName) const {
+  const OptionDescription& OptDesc = this->FindOption(OptName);
+  if (!OptDesc.isList() && !OptDesc.isParameter())
+    throw OptName
+      + ": incorrect option type - should be a list or parameter!";
+  return OptDesc;
+}
+
+const OptionDescription&
+OptionDescriptions::FindParameterListOrParameter
+(const std::string& OptName) const {
+  const OptionDescription& OptDesc = this->FindOption(OptName);
+  if ((!OptDesc.isList() && !OptDesc.isParameter()) || OptDesc.isSwitchList())
+    throw OptName
+      + ": incorrect option type - should be a parameter list or parameter!";
+  return OptDesc;
+}
+
+void OptionDescriptions::InsertDescription (const OptionDescription& o) {
+  container_type::iterator I = Descriptions.find(o.Name);
+  if (I != Descriptions.end()) {
+    OptionDescription& D = I->second;
+    D.Merge(o);
+  }
+  else {
+    Descriptions[o.Name] = o;
+  }
+}
+
+/// HandlerTable - A base class for function objects implemented as
+/// 'tables of handlers'.
+template <typename Handler>
+class HandlerTable {
+protected:
+  // Implementation details.
+
+  /// HandlerMap - A map from property names to property handlers
+  typedef StringMap<Handler> HandlerMap;
+
+  static HandlerMap Handlers_;
+  static bool staticMembersInitialized_;
+
+public:
+
+  Handler GetHandler (const std::string& HandlerName) const {
+    typename HandlerMap::iterator method = Handlers_.find(HandlerName);
+
+    if (method != Handlers_.end()) {
+      Handler h = method->second;
+      return h;
+    }
+    else {
+      throw "No handler found for property " + HandlerName + "!";
+    }
+  }
+
+  void AddHandler(const char* Property, Handler H) {
+    Handlers_[Property] = H;
+  }
+
+};
+
+template <class Handler, class FunctionObject>
+Handler GetHandler(FunctionObject* Obj, const DagInit& Dag) {
+  const std::string& HandlerName = GetOperatorName(Dag);
+  return Obj->GetHandler(HandlerName);
+}
+
+template <class FunctionObject>
+void InvokeDagInitHandler(FunctionObject* Obj, Init* I) {
+  typedef void (FunctionObject::*Handler) (const DagInit&);
+
+  const DagInit& Dag = InitPtrToDag(I);
+  Handler h = GetHandler<Handler>(Obj, Dag);
+
+  ((Obj)->*(h))(Dag);
+}
+
+template <class FunctionObject>
+void InvokeDagInitHandler(const FunctionObject* const Obj,
+                          const Init* I, unsigned IndentLevel, raw_ostream& O)
+{
+  typedef void (FunctionObject::*Handler)
+    (const DagInit&, unsigned IndentLevel, raw_ostream& O) const;
+
+  const DagInit& Dag = InitPtrToDag(I);
+  Handler h = GetHandler<Handler>(Obj, Dag);
+
+  ((Obj)->*(h))(Dag, IndentLevel, O);
+}
+
+
+template <typename H>
+typename HandlerTable<H>::HandlerMap HandlerTable<H>::Handlers_;
+
+template <typename H>
+bool HandlerTable<H>::staticMembersInitialized_ = false;
+
+
+/// CollectOptionProperties - Function object for iterating over an
+/// option property list.
+class CollectOptionProperties;
+typedef void (CollectOptionProperties::* CollectOptionPropertiesHandler)
+(const DagInit&);
+
+class CollectOptionProperties
+: public HandlerTable<CollectOptionPropertiesHandler>
+{
+private:
+
+  /// optDescs_ - OptionDescriptions table. This is where the
+  /// information is stored.
+  OptionDescription& optDesc_;
+
+public:
+
+  explicit CollectOptionProperties(OptionDescription& OD)
+    : optDesc_(OD)
+  {
+    if (!staticMembersInitialized_) {
+      AddHandler("extern", &CollectOptionProperties::onExtern);
+      AddHandler("help", &CollectOptionProperties::onHelp);
+      AddHandler("hidden", &CollectOptionProperties::onHidden);
+      AddHandler("init", &CollectOptionProperties::onInit);
+      AddHandler("multi_val", &CollectOptionProperties::onMultiVal);
+      AddHandler("one_or_more", &CollectOptionProperties::onOneOrMore);
+      AddHandler("zero_or_more", &CollectOptionProperties::onZeroOrMore);
+      AddHandler("really_hidden", &CollectOptionProperties::onReallyHidden);
+      AddHandler("required", &CollectOptionProperties::onRequired);
+      AddHandler("optional", &CollectOptionProperties::onOptional);
+      AddHandler("comma_separated", &CollectOptionProperties::onCommaSeparated);
+      AddHandler("forward_not_split",
+                 &CollectOptionProperties::onForwardNotSplit);
+
+      staticMembersInitialized_ = true;
+    }
+  }
+
+  /// operator() - Just forwards to the corresponding property
+  /// handler.
+  void operator() (Init* I) {
+    InvokeDagInitHandler(this, I);
+  }
+
+private:
+
+  /// Option property handlers --
+  /// Methods that handle option properties such as (help) or (hidden).
+
+  void onExtern (const DagInit& d) {
+    CheckNumberOfArguments(d, 0);
+    optDesc_.setExtern();
+  }
+
+  void onHelp (const DagInit& d) {
+    CheckNumberOfArguments(d, 1);
+    optDesc_.Help = EscapeQuotes(InitPtrToString(d.getArg(0)));
+  }
+
+  void onHidden (const DagInit& d) {
+    CheckNumberOfArguments(d, 0);
+    optDesc_.setHidden();
+  }
+
+  void onReallyHidden (const DagInit& d) {
+    CheckNumberOfArguments(d, 0);
+    optDesc_.setReallyHidden();
+  }
+
+  void onCommaSeparated (const DagInit& d) {
+    CheckNumberOfArguments(d, 0);
+    if (!optDesc_.isParameterList())
+      throw "'comma_separated' is valid only on parameter list options!";
+    optDesc_.setCommaSeparated();
+  }
+
+  void onForwardNotSplit (const DagInit& d) {
+    CheckNumberOfArguments(d, 0);
+    if (!optDesc_.isParameter())
+      throw "'forward_not_split' is valid only for parameter options!";
+    optDesc_.setForwardNotSplit();
+  }
+
+  void onRequired (const DagInit& d) {
+    CheckNumberOfArguments(d, 0);
+
+    optDesc_.setRequired();
+    optDesc_.CheckConsistency();
+  }
+
+  void onInit (const DagInit& d) {
+    CheckNumberOfArguments(d, 1);
+    Init* i = d.getArg(0);
+    const std::string& str = i->getAsString();
+
+    bool correct = optDesc_.isParameter() && dynamic_cast<StringInit*>(i);
+    correct |= (optDesc_.isSwitch() && (str == "true" || str == "false"));
+
+    if (!correct)
+      throw "Incorrect usage of the 'init' option property!";
+
+    optDesc_.InitVal = i;
+  }
+
+  void onOneOrMore (const DagInit& d) {
+    CheckNumberOfArguments(d, 0);
+
+    optDesc_.setOneOrMore();
+    optDesc_.CheckConsistency();
+  }
+
+  void onZeroOrMore (const DagInit& d) {
+    CheckNumberOfArguments(d, 0);
+
+    if (optDesc_.isList())
+      llvm::errs() << "Warning: specifying the 'zero_or_more' property "
+        "on a list option has no effect.\n";
+
+    optDesc_.setZeroOrMore();
+    optDesc_.CheckConsistency();
+  }
+
+  void onOptional (const DagInit& d) {
+    CheckNumberOfArguments(d, 0);
+
+    if (!optDesc_.isList())
+      llvm::errs() << "Warning: specifying the 'optional' property"
+        "on a non-list option has no effect.\n";
+
+    optDesc_.setOptional();
+    optDesc_.CheckConsistency();
+  }
+
+  void onMultiVal (const DagInit& d) {
+    CheckNumberOfArguments(d, 1);
+    int val = InitPtrToInt(d.getArg(0));
+    if (val < 2)
+      throw "Error in the 'multi_val' property: "
+        "the value must be greater than 1!";
+    if (!optDesc_.isParameterList())
+      throw "The multi_val property is valid only on list options!";
+    optDesc_.MultiVal = val;
+  }
+
+};
+
+/// AddOption - A function object that is applied to every option
+/// description. Used by CollectOptionDescriptions.
+class AddOption {
+private:
+  OptionDescriptions& OptDescs_;
+
+public:
+  explicit AddOption(OptionDescriptions& OD) : OptDescs_(OD)
+  {}
+
+  void operator()(const Init* i) {
+    const DagInit& d = InitPtrToDag(i);
+    CheckNumberOfArguments(d, 1);
+
+    const OptionType::OptionType Type =
+      stringToOptionType(GetOperatorName(d));
+    const std::string& Name = InitPtrToString(d.getArg(0));
+
+    OptionDescription OD(Type, Name);
+
+    if (!OD.isExtern())
+      CheckNumberOfArguments(d, 2);
+
+    if (OD.isAlias()) {
+      // Aliases store the aliased option name in the 'Help' field.
+      OD.Help = InitPtrToString(d.getArg(1));
+    }
+    else if (!OD.isExtern()) {
+      processOptionProperties(d, OD);
+    }
+    OptDescs_.InsertDescription(OD);
+  }
+
+private:
+  /// processOptionProperties - Go through the list of option
+  /// properties and call a corresponding handler for each.
+  static void processOptionProperties (const DagInit& d, OptionDescription& o) {
+    CheckNumberOfArguments(d, 2);
+    DagInit::const_arg_iterator B = d.arg_begin();
+    // Skip the first argument: it's always the option name.
+    ++B;
+    std::for_each(B, d.arg_end(), CollectOptionProperties(o));
+  }
+
+};
+
+/// CollectOptionDescriptions - Collects option properties from all
+/// OptionLists.
+void CollectOptionDescriptions (RecordVector::const_iterator B,
+                                RecordVector::const_iterator E,
+                                OptionDescriptions& OptDescs)
+{
+  // For every OptionList:
+  for (; B!=E; ++B) {
+    RecordVector::value_type T = *B;
+    // Throws an exception if the value does not exist.
+    ListInit* PropList = T->getValueAsListInit("options");
+
+    // For every option description in this list:
+    // collect the information and
+    std::for_each(PropList->begin(), PropList->end(), AddOption(OptDescs));
+  }
+}
+
+// Tool information record
+
+namespace ToolFlags {
+  enum ToolFlags { Join = 0x1, Sink = 0x2 };
+}
+
+struct ToolDescription : public RefCountedBase<ToolDescription> {
+  std::string Name;
+  Init* CmdLine;
+  Init* Actions;
+  StrVector InLanguage;
+  std::string InFileOption;
+  std::string OutFileOption;
+  std::string OutLanguage;
+  std::string OutputSuffix;
+  unsigned Flags;
+  const Init* OnEmpty;
+
+  // Various boolean properties
+  void setSink()      { Flags |= ToolFlags::Sink; }
+  bool isSink() const { return Flags & ToolFlags::Sink; }
+  void setJoin()      { Flags |= ToolFlags::Join; }
+  bool isJoin() const { return Flags & ToolFlags::Join; }
+
+  // Default ctor here is needed because StringMap can only store
+  // DefaultConstructible objects
+  ToolDescription ()
+    : CmdLine(0), Actions(0), OutFileOption("-o"),
+      Flags(0), OnEmpty(0)
+  {}
+  ToolDescription (const std::string& n)
+    : Name(n), CmdLine(0), Actions(0), OutFileOption("-o"),
+      Flags(0), OnEmpty(0)
+  {}
+};
+
+/// ToolDescriptions - A list of Tool information records.
+typedef std::vector<IntrusiveRefCntPtr<ToolDescription> > ToolDescriptions;
+
+
+/// CollectToolProperties - Function object for iterating over a list of
+/// tool property records.
+
+class CollectToolProperties;
+typedef void (CollectToolProperties::* CollectToolPropertiesHandler)
+(const DagInit&);
+
+class CollectToolProperties : public HandlerTable<CollectToolPropertiesHandler>
+{
+private:
+
+  /// toolDesc_ - Properties of the current Tool. This is where the
+  /// information is stored.
+  ToolDescription& toolDesc_;
+
+public:
+
+  explicit CollectToolProperties (ToolDescription& d)
+    : toolDesc_(d)
+  {
+    if (!staticMembersInitialized_) {
+
+      AddHandler("actions", &CollectToolProperties::onActions);
+      AddHandler("command", &CollectToolProperties::onCommand);
+      AddHandler("in_language", &CollectToolProperties::onInLanguage);
+      AddHandler("join", &CollectToolProperties::onJoin);
+      AddHandler("out_language", &CollectToolProperties::onOutLanguage);
+
+      AddHandler("out_file_option", &CollectToolProperties::onOutFileOption);
+      AddHandler("in_file_option", &CollectToolProperties::onInFileOption);
+
+      AddHandler("output_suffix", &CollectToolProperties::onOutputSuffix);
+      AddHandler("sink", &CollectToolProperties::onSink);
+      AddHandler("works_on_empty", &CollectToolProperties::onWorksOnEmpty);
+
+      staticMembersInitialized_ = true;
+    }
+  }
+
+  void operator() (Init* I) {
+    InvokeDagInitHandler(this, I);
+  }
+
+private:
+
+  /// Property handlers --
+  /// Functions that extract information about tool properties from
+  /// DAG representation.
+
+  void onActions (const DagInit& d) {
+    CheckNumberOfArguments(d, 1);
+    Init* Case = d.getArg(0);
+    if (typeid(*Case) != typeid(DagInit) ||
+        GetOperatorName(static_cast<DagInit&>(*Case)) != "case")
+      throw "The argument to (actions) should be a 'case' construct!";
+    toolDesc_.Actions = Case;
+  }
+
+  void onCommand (const DagInit& d) {
+    CheckNumberOfArguments(d, 1);
+    toolDesc_.CmdLine = d.getArg(0);
+  }
+
+  void onInLanguage (const DagInit& d) {
+    CheckNumberOfArguments(d, 1);
+    Init* arg = d.getArg(0);
+
+    // Find out the argument's type.
+    if (typeid(*arg) == typeid(StringInit)) {
+      // It's a string.
+      toolDesc_.InLanguage.push_back(InitPtrToString(arg));
+    }
+    else {
+      // It's a list.
+      const ListInit& lst = InitPtrToList(arg);
+      StrVector& out = toolDesc_.InLanguage;
+
+      // Copy strings to the output vector.
+      for (ListInit::const_iterator B = lst.begin(), E = lst.end();
+           B != E; ++B) {
+        out.push_back(InitPtrToString(*B));
+      }
+
+      // Remove duplicates.
+      std::sort(out.begin(), out.end());
+      StrVector::iterator newE = std::unique(out.begin(), out.end());
+      out.erase(newE, out.end());
+    }
+  }
+
+  void onJoin (const DagInit& d) {
+    CheckNumberOfArguments(d, 0);
+    toolDesc_.setJoin();
+  }
+
+  void onOutLanguage (const DagInit& d) {
+    CheckNumberOfArguments(d, 1);
+    toolDesc_.OutLanguage = InitPtrToString(d.getArg(0));
+  }
+
+  void onOutFileOption (const DagInit& d) {
+    CheckNumberOfArguments(d, 1);
+    toolDesc_.OutFileOption = InitPtrToString(d.getArg(0));
+  }
+
+  void onInFileOption (const DagInit& d) {
+    CheckNumberOfArguments(d, 1);
+    toolDesc_.InFileOption = InitPtrToString(d.getArg(0));
+  }
+
+  void onOutputSuffix (const DagInit& d) {
+    CheckNumberOfArguments(d, 1);
+    toolDesc_.OutputSuffix = InitPtrToString(d.getArg(0));
+  }
+
+  void onSink (const DagInit& d) {
+    CheckNumberOfArguments(d, 0);
+    toolDesc_.setSink();
+  }
+
+  void onWorksOnEmpty (const DagInit& d) {
+    toolDesc_.OnEmpty = d.getArg(0);
+  }
+
+};
+
+/// CollectToolDescriptions - Gather information about tool properties
+/// from the parsed TableGen data (basically a wrapper for the
+/// CollectToolProperties function object).
+void CollectToolDescriptions (RecordVector::const_iterator B,
+                              RecordVector::const_iterator E,
+                              ToolDescriptions& ToolDescs)
+{
+  // Iterate over a properties list of every Tool definition
+  for (;B!=E;++B) {
+    const Record* T = *B;
+    // Throws an exception if the value does not exist.
+    ListInit* PropList = T->getValueAsListInit("properties");
+
+    IntrusiveRefCntPtr<ToolDescription>
+      ToolDesc(new ToolDescription(T->getName()));
+
+    std::for_each(PropList->begin(), PropList->end(),
+                  CollectToolProperties(*ToolDesc));
+    ToolDescs.push_back(ToolDesc);
+  }
+}
+
+/// FillInEdgeVector - Merge all compilation graph definitions into
+/// one single edge list.
+void FillInEdgeVector(RecordVector::const_iterator B,
+                      RecordVector::const_iterator E, RecordVector& Out) {
+  for (; B != E; ++B) {
+    const ListInit* edges = (*B)->getValueAsListInit("edges");
+
+    for (unsigned i = 0; i < edges->size(); ++i)
+      Out.push_back(edges->getElementAsRecord(i));
+  }
+}
+
+/// CalculatePriority - Calculate the priority of this plugin.
+int CalculatePriority(RecordVector::const_iterator B,
+                      RecordVector::const_iterator E) {
+  int priority = 0;
+
+  if (B != E) {
+    priority  = static_cast<int>((*B)->getValueAsInt("priority"));
+
+    if (++B != E)
+      throw "More than one 'PluginPriority' instance found: "
+        "most probably an error!";
+  }
+
+  return priority;
+}
+
+/// NotInGraph - Helper function object for FilterNotInGraph.
+struct NotInGraph {
+private:
+  const llvm::StringSet<>& ToolsInGraph_;
+
+public:
+  NotInGraph(const llvm::StringSet<>& ToolsInGraph)
+  : ToolsInGraph_(ToolsInGraph)
+  {}
+
+  bool operator()(const IntrusiveRefCntPtr<ToolDescription>& x) {
+    return (ToolsInGraph_.count(x->Name) == 0);
+  }
+};
+
+/// FilterNotInGraph - Filter out from ToolDescs all Tools not
+/// mentioned in the compilation graph definition.
+void FilterNotInGraph (const RecordVector& EdgeVector,
+                       ToolDescriptions& ToolDescs) {
+
+  // List all tools mentioned in the graph.
+  llvm::StringSet<> ToolsInGraph;
+
+  for (RecordVector::const_iterator B = EdgeVector.begin(),
+         E = EdgeVector.end(); B != E; ++B) {
+
+    const Record* Edge = *B;
+    const std::string& NodeA = Edge->getValueAsString("a");
+    const std::string& NodeB = Edge->getValueAsString("b");
+
+    if (NodeA != "root")
+      ToolsInGraph.insert(NodeA);
+    ToolsInGraph.insert(NodeB);
+  }
+
+  // Filter ToolPropertiesList.
+  ToolDescriptions::iterator new_end =
+    std::remove_if(ToolDescs.begin(), ToolDescs.end(),
+                   NotInGraph(ToolsInGraph));
+  ToolDescs.erase(new_end, ToolDescs.end());
+}
+
+/// FillInToolToLang - Fills in two tables that map tool names to
+/// (input, output) languages.  Helper function used by TypecheckGraph().
+void FillInToolToLang (const ToolDescriptions& ToolDescs,
+                       StringMap<StringSet<> >& ToolToInLang,
+                       StringMap<std::string>& ToolToOutLang) {
+  for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
+         E = ToolDescs.end(); B != E; ++B) {
+    const ToolDescription& D = *(*B);
+    for (StrVector::const_iterator B = D.InLanguage.begin(),
+           E = D.InLanguage.end(); B != E; ++B)
+      ToolToInLang[D.Name].insert(*B);
+    ToolToOutLang[D.Name] = D.OutLanguage;
+  }
+}
+
+/// TypecheckGraph - Check that names for output and input languages
+/// on all edges do match. This doesn't do much when the information
+/// about the whole graph is not available (i.e. when compiling most
+/// plugins).
+void TypecheckGraph (const RecordVector& EdgeVector,
+                     const ToolDescriptions& ToolDescs) {
+  StringMap<StringSet<> > ToolToInLang;
+  StringMap<std::string> ToolToOutLang;
+
+  FillInToolToLang(ToolDescs, ToolToInLang, ToolToOutLang);
+  StringMap<std::string>::iterator IAE = ToolToOutLang.end();
+  StringMap<StringSet<> >::iterator IBE = ToolToInLang.end();
+
+  for (RecordVector::const_iterator B = EdgeVector.begin(),
+         E = EdgeVector.end(); B != E; ++B) {
+    const Record* Edge = *B;
+    const std::string& NodeA = Edge->getValueAsString("a");
+    const std::string& NodeB = Edge->getValueAsString("b");
+    StringMap<std::string>::iterator IA = ToolToOutLang.find(NodeA);
+    StringMap<StringSet<> >::iterator IB = ToolToInLang.find(NodeB);
+
+    if (NodeA != "root") {
+      if (IA != IAE && IB != IBE && IB->second.count(IA->second) == 0)
+        throw "Edge " + NodeA + "->" + NodeB
+          + ": output->input language mismatch";
+    }
+
+    if (NodeB == "root")
+      throw "Edges back to the root are not allowed!";
+  }
+}
+
+/// WalkCase - Walks the 'case' expression DAG and invokes
+/// TestCallback on every test, and StatementCallback on every
+/// statement. Handles 'case' nesting, but not the 'and' and 'or'
+/// combinators (that is, they are passed directly to TestCallback).
+/// TestCallback must have type 'void TestCallback(const DagInit*, unsigned
+/// IndentLevel, bool FirstTest)'.
+/// StatementCallback must have type 'void StatementCallback(const Init*,
+/// unsigned IndentLevel)'.
+template <typename F1, typename F2>
+void WalkCase(const Init* Case, F1 TestCallback, F2 StatementCallback,
+              unsigned IndentLevel = 0)
+{
+  const DagInit& d = InitPtrToDag(Case);
+
+  // Error checks.
+  if (GetOperatorName(d) != "case")
+    throw "WalkCase should be invoked only on 'case' expressions!";
+
+  if (d.getNumArgs() < 2)
+    throw "There should be at least one clause in the 'case' expression:\n"
+      + d.getAsString();
+
+  // Main loop.
+  bool even = false;
+  const unsigned numArgs = d.getNumArgs();
+  unsigned i = 1;
+  for (DagInit::const_arg_iterator B = d.arg_begin(), E = d.arg_end();
+       B != E; ++B) {
+    Init* arg = *B;
+
+    if (!even)
+    {
+      // Handle test.
+      const DagInit& Test = InitPtrToDag(arg);
+
+      if (GetOperatorName(Test) == "default" && (i+1 != numArgs))
+        throw "The 'default' clause should be the last in the "
+          "'case' construct!";
+      if (i == numArgs)
+        throw "Case construct handler: no corresponding action "
+          "found for the test " + Test.getAsString() + '!';
+
+      TestCallback(Test, IndentLevel, (i == 1));
+    }
+    else
+    {
+      if (dynamic_cast<DagInit*>(arg)
+          && GetOperatorName(static_cast<DagInit&>(*arg)) == "case") {
+        // Nested 'case'.
+        WalkCase(arg, TestCallback, StatementCallback, IndentLevel + Indent1);
+      }
+
+      // Handle statement.
+      StatementCallback(arg, IndentLevel);
+    }
+
+    ++i;
+    even = !even;
+  }
+}
+
+/// ExtractOptionNames - A helper function object used by
+/// CheckForSuperfluousOptions() to walk the 'case' DAG.
+class ExtractOptionNames {
+  llvm::StringSet<>& OptionNames_;
+
+  void processDag(const Init* Statement) {
+    const DagInit& Stmt = InitPtrToDag(Statement);
+    const std::string& ActionName = GetOperatorName(Stmt);
+    if (ActionName == "forward" || ActionName == "forward_as" ||
+        ActionName == "forward_value" ||
+        ActionName == "forward_transformed_value" ||
+        ActionName == "switch_on" || ActionName == "any_switch_on" ||
+        ActionName == "parameter_equals" ||
+        ActionName == "element_in_list" || ActionName == "not_empty" ||
+        ActionName == "empty") {
+      CheckNumberOfArguments(Stmt, 1);
+
+      Init* Arg = Stmt.getArg(0);
+      if (typeid(*Arg) == typeid(StringInit)) {
+        const std::string& Name = InitPtrToString(Arg);
+        OptionNames_.insert(Name);
+      }
+      else {
+        // It's a list.
+        const ListInit& List = InitPtrToList(Arg);
+        for (ListInit::const_iterator B = List.begin(), E = List.end();
+             B != E; ++B) {
+          const std::string& Name = InitPtrToString(*B);
+          OptionNames_.insert(Name);
+        }
+      }
+    }
+    else if (ActionName == "and" || ActionName == "or" || ActionName == "not") {
+      for (unsigned i = 0, NumArgs = Stmt.getNumArgs(); i < NumArgs; ++i) {
+        this->processDag(Stmt.getArg(i));
+      }
+    }
+  }
+
+public:
+  ExtractOptionNames(llvm::StringSet<>& OptionNames) : OptionNames_(OptionNames)
+  {}
+
+  void operator()(const Init* Statement) {
+    if (typeid(*Statement) == typeid(ListInit)) {
+      const ListInit& DagList = *static_cast<const ListInit*>(Statement);
+      for (ListInit::const_iterator B = DagList.begin(), E = DagList.end();
+           B != E; ++B)
+        this->processDag(*B);
+    }
+    else {
+      this->processDag(Statement);
+    }
+  }
+
+  void operator()(const DagInit& Test, unsigned, bool) {
+    this->operator()(&Test);
+  }
+  void operator()(const Init* Statement, unsigned) {
+    this->operator()(Statement);
+  }
+};
+
+/// CheckForSuperfluousOptions - Check that there are no side
+/// effect-free options (specified only in the OptionList). Otherwise,
+/// output a warning.
+void CheckForSuperfluousOptions (const RecordVector& Edges,
+                                 const ToolDescriptions& ToolDescs,
+                                 const OptionDescriptions& OptDescs) {
+  llvm::StringSet<> nonSuperfluousOptions;
+
+  // Add all options mentioned in the ToolDesc.Actions to the set of
+  // non-superfluous options.
+  for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
+         E = ToolDescs.end(); B != E; ++B) {
+    const ToolDescription& TD = *(*B);
+    ExtractOptionNames Callback(nonSuperfluousOptions);
+    if (TD.Actions)
+      WalkCase(TD.Actions, Callback, Callback);
+  }
+
+  // Add all options mentioned in the 'case' clauses of the
+  // OptionalEdges of the compilation graph to the set of
+  // non-superfluous options.
+  for (RecordVector::const_iterator B = Edges.begin(), E = Edges.end();
+       B != E; ++B) {
+    const Record* Edge = *B;
+    DagInit& Weight = *Edge->getValueAsDag("weight");
+
+    if (!IsDagEmpty(Weight))
+      WalkCase(&Weight, ExtractOptionNames(nonSuperfluousOptions), Id());
+  }
+
+  // Check that all options in OptDescs belong to the set of
+  // non-superfluous options.
+  for (OptionDescriptions::const_iterator B = OptDescs.begin(),
+         E = OptDescs.end(); B != E; ++B) {
+    const OptionDescription& Val = B->second;
+    if (!nonSuperfluousOptions.count(Val.Name)
+        && Val.Type != OptionType::Alias)
+      llvm::errs() << "Warning: option '-" << Val.Name << "' has no effect! "
+        "Probable cause: this option is specified only in the OptionList.\n";
+  }
+}
+
+/// EmitCaseTest0Args - Helper function used by EmitCaseConstructHandler().
+bool EmitCaseTest0Args(const std::string& TestName, raw_ostream& O) {
+  if (TestName == "single_input_file") {
+    O << "InputFilenames.size() == 1";
+    return true;
+  }
+  else if (TestName == "multiple_input_files") {
+    O << "InputFilenames.size() > 1";
+    return true;
+  }
+
+  return false;
+}
+
+/// EmitListTest - Helper function used by EmitCaseTest1ArgList().
+template <typename F>
+void EmitListTest(const ListInit& L, const char* LogicOp,
+                  F Callback, raw_ostream& O)
+{
+  // This is a lot like EmitLogicalOperationTest, but works on ListInits instead
+  // of Dags...
+  bool isFirst = true;
+  for (ListInit::const_iterator B = L.begin(), E = L.end(); B != E; ++B) {
+    if (isFirst)
+      isFirst = false;
+    else
+      O << ' ' << LogicOp << ' ';
+    Callback(InitPtrToString(*B), O);
+  }
+}
+
+// Callbacks for use with EmitListTest.
+
+class EmitSwitchOn {
+  const OptionDescriptions& OptDescs_;
+public:
+  EmitSwitchOn(const OptionDescriptions& OptDescs) : OptDescs_(OptDescs)
+  {}
+
+  void operator()(const std::string& OptName, raw_ostream& O) const {
+    const OptionDescription& OptDesc = OptDescs_.FindSwitch(OptName);
+    O << OptDesc.GenVariableName();
+  }
+};
+
+class EmitEmptyTest {
+  bool EmitNegate_;
+  const OptionDescriptions& OptDescs_;
+public:
+  EmitEmptyTest(bool EmitNegate, const OptionDescriptions& OptDescs)
+    : EmitNegate_(EmitNegate), OptDescs_(OptDescs)
+  {}
+
+  void operator()(const std::string& OptName, raw_ostream& O) const {
+    const char* Neg = (EmitNegate_ ? "!" : "");
+    if (OptName == "o") {
+      O << Neg << "OutputFilename.empty()";
+    }
+    else if (OptName == "save-temps") {
+      O << Neg << "(SaveTemps == SaveTempsEnum::Unset)";
+    }
+    else {
+      const OptionDescription& OptDesc = OptDescs_.FindListOrParameter(OptName);
+      O << Neg << OptDesc.GenVariableName() << ".empty()";
+    }
+  }
+};
+
+
+/// EmitCaseTest1ArgList - Helper function used by EmitCaseTest1Arg();
+bool EmitCaseTest1ArgList(const std::string& TestName,
+                          const DagInit& d,
+                          const OptionDescriptions& OptDescs,
+                          raw_ostream& O) {
+  const ListInit& L = InitPtrToList(d.getArg(0));
+
+  if (TestName == "any_switch_on") {
+    EmitListTest(L, "||", EmitSwitchOn(OptDescs), O);
+    return true;
+  }
+  else if (TestName == "switch_on") {
+    EmitListTest(L, "&&", EmitSwitchOn(OptDescs), O);
+    return true;
+  }
+  else if (TestName == "any_not_empty") {
+    EmitListTest(L, "||", EmitEmptyTest(true, OptDescs), O);
+    return true;
+  }
+  else if (TestName == "any_empty") {
+    EmitListTest(L, "||", EmitEmptyTest(false, OptDescs), O);
+    return true;
+  }
+  else if (TestName == "not_empty") {
+    EmitListTest(L, "&&", EmitEmptyTest(true, OptDescs), O);
+    return true;
+  }
+  else if (TestName == "empty") {
+    EmitListTest(L, "&&", EmitEmptyTest(false, OptDescs), O);
+    return true;
+  }
+
+  return false;
+}
+
+/// EmitCaseTest1ArgStr - Helper function used by EmitCaseTest1Arg();
+bool EmitCaseTest1ArgStr(const std::string& TestName,
+                         const DagInit& d,
+                         const OptionDescriptions& OptDescs,
+                         raw_ostream& O) {
+  const std::string& OptName = InitPtrToString(d.getArg(0));
+
+  if (TestName == "switch_on") {
+    apply(EmitSwitchOn(OptDescs), OptName, O);
+    return true;
+  }
+  else if (TestName == "input_languages_contain") {
+    O << "InLangs.count(\"" << OptName << "\") != 0";
+    return true;
+  }
+  else if (TestName == "in_language") {
+    // This works only for single-argument Tool::GenerateAction. Join
+    // tools can process several files in different languages simultaneously.
+
+    // TODO: make this work with Edge::Weight (if possible).
+    O << "LangMap.GetLanguage(inFile) == \"" << OptName << '\"';
+    return true;
+  }
+  else if (TestName == "not_empty" || TestName == "empty") {
+    bool EmitNegate = (TestName == "not_empty");
+    apply(EmitEmptyTest(EmitNegate, OptDescs), OptName, O);
+    return true;
+  }
+
+  return false;
+}
+
+/// EmitCaseTest1Arg - Helper function used by EmitCaseConstructHandler();
+bool EmitCaseTest1Arg(const std::string& TestName,
+                      const DagInit& d,
+                      const OptionDescriptions& OptDescs,
+                      raw_ostream& O) {
+  CheckNumberOfArguments(d, 1);
+  if (typeid(*d.getArg(0)) == typeid(ListInit))
+    return EmitCaseTest1ArgList(TestName, d, OptDescs, O);
+  else
+    return EmitCaseTest1ArgStr(TestName, d, OptDescs, O);
+}
+
+/// EmitCaseTest2Args - Helper function used by EmitCaseConstructHandler().
+bool EmitCaseTest2Args(const std::string& TestName,
+                       const DagInit& d,
+                       unsigned IndentLevel,
+                       const OptionDescriptions& OptDescs,
+                       raw_ostream& O) {
+  CheckNumberOfArguments(d, 2);
+  const std::string& OptName = InitPtrToString(d.getArg(0));
+  const std::string& OptArg = InitPtrToString(d.getArg(1));
+
+  if (TestName == "parameter_equals") {
+    const OptionDescription& OptDesc = OptDescs.FindParameter(OptName);
+    O << OptDesc.GenVariableName() << " == \"" << OptArg << "\"";
+    return true;
+  }
+  else if (TestName == "element_in_list") {
+    const OptionDescription& OptDesc = OptDescs.FindParameterList(OptName);
+    const std::string& VarName = OptDesc.GenVariableName();
+    O << "std::find(" << VarName << ".begin(),\n";
+    O.indent(IndentLevel + Indent1)
+      << VarName << ".end(), \""
+      << OptArg << "\") != " << VarName << ".end()";
+    return true;
+  }
+
+  return false;
+}
+
+// Forward declaration.
+// EmitLogicalOperationTest and EmitCaseTest are mutually recursive.
+void EmitCaseTest(const DagInit& d, unsigned IndentLevel,
+                  const OptionDescriptions& OptDescs,
+                  raw_ostream& O);
+
+/// EmitLogicalOperationTest - Helper function used by
+/// EmitCaseConstructHandler.
+void EmitLogicalOperationTest(const DagInit& d, const char* LogicOp,
+                              unsigned IndentLevel,
+                              const OptionDescriptions& OptDescs,
+                              raw_ostream& O) {
+  O << '(';
+  for (unsigned j = 0, NumArgs = d.getNumArgs(); j < NumArgs; ++j) {
+    const DagInit& InnerTest = InitPtrToDag(d.getArg(j));
+    EmitCaseTest(InnerTest, IndentLevel, OptDescs, O);
+    if (j != NumArgs - 1) {
+      O << ")\n";
+      O.indent(IndentLevel + Indent1) << ' ' << LogicOp << " (";
+    }
+    else {
+      O << ')';
+    }
+  }
+}
+
+void EmitLogicalNot(const DagInit& d, unsigned IndentLevel,
+                    const OptionDescriptions& OptDescs, raw_ostream& O)
+{
+  CheckNumberOfArguments(d, 1);
+  const DagInit& InnerTest = InitPtrToDag(d.getArg(0));
+  O << "! (";
+  EmitCaseTest(InnerTest, IndentLevel, OptDescs, O);
+  O << ")";
+}
+
+/// EmitCaseTest - Helper function used by EmitCaseConstructHandler.
+void EmitCaseTest(const DagInit& d, unsigned IndentLevel,
+                  const OptionDescriptions& OptDescs,
+                  raw_ostream& O) {
+  const std::string& TestName = GetOperatorName(d);
+
+  if (TestName == "and")
+    EmitLogicalOperationTest(d, "&&", IndentLevel, OptDescs, O);
+  else if (TestName == "or")
+    EmitLogicalOperationTest(d, "||", IndentLevel, OptDescs, O);
+  else if (TestName == "not")
+    EmitLogicalNot(d, IndentLevel, OptDescs, O);
+  else if (EmitCaseTest0Args(TestName, O))
+    return;
+  else if (EmitCaseTest1Arg(TestName, d, OptDescs, O))
+    return;
+  else if (EmitCaseTest2Args(TestName, d, IndentLevel, OptDescs, O))
+    return;
+  else
+    throw "Unknown test '" + TestName + "' used in the 'case' construct!";
+}
+
+
+/// EmitCaseTestCallback - Callback used by EmitCaseConstructHandler.
+class EmitCaseTestCallback {
+  bool EmitElseIf_;
+  const OptionDescriptions& OptDescs_;
+  raw_ostream& O_;
+public:
+
+  EmitCaseTestCallback(bool EmitElseIf,
+                       const OptionDescriptions& OptDescs, raw_ostream& O)
+    : EmitElseIf_(EmitElseIf), OptDescs_(OptDescs), O_(O)
+  {}
+
+  void operator()(const DagInit& Test, unsigned IndentLevel, bool FirstTest)
+  {
+    if (GetOperatorName(Test) == "default") {
+      O_.indent(IndentLevel) << "else {\n";
+    }
+    else {
+      O_.indent(IndentLevel)
+        << ((!FirstTest && EmitElseIf_) ? "else if (" : "if (");
+      EmitCaseTest(Test, IndentLevel, OptDescs_, O_);
+      O_ << ") {\n";
+    }
+  }
+};
+
+/// EmitCaseStatementCallback - Callback used by EmitCaseConstructHandler.
+template <typename F>
+class EmitCaseStatementCallback {
+  F Callback_;
+  raw_ostream& O_;
+public:
+
+  EmitCaseStatementCallback(F Callback, raw_ostream& O)
+    : Callback_(Callback), O_(O)
+  {}
+
+  void operator() (const Init* Statement, unsigned IndentLevel) {
+
+    // Ignore nested 'case' DAG.
+    if (!(dynamic_cast<const DagInit*>(Statement) &&
+          GetOperatorName(static_cast<const DagInit&>(*Statement)) == "case")) {
+      if (typeid(*Statement) == typeid(ListInit)) {
+        const ListInit& DagList = *static_cast<const ListInit*>(Statement);
+        for (ListInit::const_iterator B = DagList.begin(), E = DagList.end();
+             B != E; ++B)
+          Callback_(*B, (IndentLevel + Indent1), O_);
+      }
+      else {
+        Callback_(Statement, (IndentLevel + Indent1), O_);
+      }
+    }
+    O_.indent(IndentLevel) << "}\n";
+  }
+
+};
+
+/// EmitCaseConstructHandler - Emit code that handles the 'case'
+/// construct. Takes a function object that should emit code for every case
+/// clause. Implemented on top of WalkCase.
+/// Callback's type is void F(const Init* Statement, unsigned IndentLevel,
+/// raw_ostream& O).
+/// EmitElseIf parameter controls the type of condition that is emitted ('if
+/// (..) {..} else if (..) {} .. else {..}' vs. 'if (..) {..} if(..)  {..}
+/// .. else {..}').
+template <typename F>
+void EmitCaseConstructHandler(const Init* Case, unsigned IndentLevel,
+                              F Callback, bool EmitElseIf,
+                              const OptionDescriptions& OptDescs,
+                              raw_ostream& O) {
+  WalkCase(Case, EmitCaseTestCallback(EmitElseIf, OptDescs, O),
+           EmitCaseStatementCallback<F>(Callback, O), IndentLevel);
+}
+
+/// TokenizeCmdLine - converts from
+/// "$CALL(HookName, 'Arg1', 'Arg2')/path -arg1 -arg2" to
+/// ["$CALL(", "HookName", "Arg1", "Arg2", ")/path", "-arg1", "-arg2"].
+void TokenizeCmdLine(const std::string& CmdLine, StrVector& Out) {
+  const char* Delimiters = " \t\n\v\f\r";
+  enum TokenizerState
+  { Normal, SpecialCommand, InsideSpecialCommand, InsideQuotationMarks }
+  cur_st  = Normal;
+
+  if (CmdLine.empty())
+    return;
+  Out.push_back("");
+
+  std::string::size_type B = CmdLine.find_first_not_of(Delimiters),
+    E = CmdLine.size();
+
+  for (; B != E; ++B) {
+    char cur_ch = CmdLine[B];
+
+    switch (cur_st) {
+    case Normal:
+      if (cur_ch == '$') {
+        cur_st = SpecialCommand;
+        break;
+      }
+      if (OneOf(Delimiters, cur_ch)) {
+        // Skip whitespace
+        B = CmdLine.find_first_not_of(Delimiters, B);
+        if (B == std::string::npos) {
+          B = E-1;
+          continue;
+        }
+        --B;
+        Out.push_back("");
+        continue;
+      }
+      break;
+
+
+    case SpecialCommand:
+      if (OneOf(Delimiters, cur_ch)) {
+        cur_st = Normal;
+        Out.push_back("");
+        continue;
+      }
+      if (cur_ch == '(') {
+        Out.push_back("");
+        cur_st = InsideSpecialCommand;
+        continue;
+      }
+      break;
+
+    case InsideSpecialCommand:
+      if (OneOf(Delimiters, cur_ch)) {
+        continue;
+      }
+      if (cur_ch == '\'') {
+        cur_st = InsideQuotationMarks;
+        Out.push_back("");
+        continue;
+      }
+      if (cur_ch == ')') {
+        cur_st = Normal;
+        Out.push_back("");
+      }
+      if (cur_ch == ',') {
+        continue;
+      }
+
+      break;
+
+    case InsideQuotationMarks:
+      if (cur_ch == '\'') {
+        cur_st = InsideSpecialCommand;
+        continue;
+      }
+      break;
+    }
+
+    Out.back().push_back(cur_ch);
+  }
+}
+
+/// SubstituteCall - Given "$CALL(HookName, [Arg1 [, Arg2 [...]]])", output
+/// "hooks::HookName([Arg1 [, Arg2 [, ...]]])". Helper function used by
+/// SubstituteSpecialCommands().
+StrVector::const_iterator
+SubstituteCall (StrVector::const_iterator Pos,
+                StrVector::const_iterator End,
+                bool IsJoin, raw_ostream& O)
+{
+  const char* errorMessage = "Syntax error in $CALL invocation!";
+  CheckedIncrement(Pos, End, errorMessage);
+  const std::string& CmdName = *Pos;
+
+  if (CmdName == ")")
+    throw "$CALL invocation: empty argument list!";
+
+  O << "hooks::";
+  O << CmdName << "(";
+
+
+  bool firstIteration = true;
+  while (true) {
+    CheckedIncrement(Pos, End, errorMessage);
+    const std::string& Arg = *Pos;
+    assert(Arg.size() != 0);
+
+    if (Arg[0] == ')')
+      break;
+
+    if (firstIteration)
+      firstIteration = false;
+    else
+      O << ", ";
+
+    if (Arg == "$INFILE") {
+      if (IsJoin)
+        throw "$CALL(Hook, $INFILE) can't be used with a Join tool!";
+      else
+        O << "inFile.c_str()";
+    }
+    else {
+      O << '"' << Arg << '"';
+    }
+  }
+
+  O << ')';
+
+  return Pos;
+}
+
+/// SubstituteEnv - Given '$ENV(VAR_NAME)', output 'getenv("VAR_NAME")'. Helper
+/// function used by SubstituteSpecialCommands().
+StrVector::const_iterator
+SubstituteEnv (StrVector::const_iterator Pos,
+               StrVector::const_iterator End, raw_ostream& O)
+{
+  const char* errorMessage = "Syntax error in $ENV invocation!";
+  CheckedIncrement(Pos, End, errorMessage);
+  const std::string& EnvName = *Pos;
+
+  if (EnvName == ")")
+    throw "$ENV invocation: empty argument list!";
+
+  O << "checkCString(std::getenv(\"";
+  O << EnvName;
+  O << "\"))";
+
+  CheckedIncrement(Pos, End, errorMessage);
+
+  return Pos;
+}
+
+/// SubstituteSpecialCommands - Given an invocation of $CALL or $ENV, output
+/// handler code. Helper function used by EmitCmdLineVecFill().
+StrVector::const_iterator
+SubstituteSpecialCommands (StrVector::const_iterator Pos,
+                           StrVector::const_iterator End,
+                           bool IsJoin, raw_ostream& O)
+{
+
+  const std::string& cmd = *Pos;
+
+  // Perform substitution.
+  if (cmd == "$CALL") {
+    Pos = SubstituteCall(Pos, End, IsJoin, O);
+  }
+  else if (cmd == "$ENV") {
+    Pos = SubstituteEnv(Pos, End, O);
+  }
+  else {
+    throw "Unknown special command: " + cmd;
+  }
+
+  // Handle '$CMD(ARG)/additional/text'.
+  const std::string& Leftover = *Pos;
+  assert(Leftover.at(0) == ')');
+  if (Leftover.size() != 1)
+    O << " + std::string(\"" << (Leftover.c_str() + 1) << "\")";
+
+  return Pos;
+}
+
+/// EmitCmdLineVecFill - Emit code that fills in the command line
+/// vector. Helper function used by EmitGenerateActionMethod().
+void EmitCmdLineVecFill(const Init* CmdLine, const std::string& ToolName,
+                        bool IsJoin, unsigned IndentLevel,
+                        raw_ostream& O) {
+  StrVector StrVec;
+  TokenizeCmdLine(InitPtrToString(CmdLine), StrVec);
+
+  if (StrVec.empty())
+    throw "Tool '" + ToolName + "' has empty command line!";
+
+  StrVector::const_iterator B = StrVec.begin(), E = StrVec.end();
+
+  // Emit the command itself.
+  assert(!StrVec[0].empty());
+  O.indent(IndentLevel) << "cmd = ";
+  if (StrVec[0][0] == '$') {
+    B = SubstituteSpecialCommands(B, E, IsJoin, O);
+    ++B;
+  }
+  else {
+    O << '"' << StrVec[0] << '"';
+    ++B;
+  }
+  O << ";\n";
+
+  // Go through the command arguments.
+  assert(B <= E);
+  for (; B != E; ++B) {
+    const std::string& cmd = *B;
+
+    assert(!cmd.empty());
+    O.indent(IndentLevel);
+
+    if (cmd.at(0) == '$') {
+      O << "vec.push_back(std::make_pair(0, ";
+      B = SubstituteSpecialCommands(B, E, IsJoin, O);
+      O << "));\n";
+    }
+    else {
+      O << "vec.push_back(std::make_pair(0, \"" << cmd << "\"));\n";
+    }
+  }
+
+}
+
+/// EmitForEachListElementCycleHeader - Emit common code for iterating through
+/// all elements of a list. Helper function used by
+/// EmitForwardOptionPropertyHandlingCode.
+void EmitForEachListElementCycleHeader (const OptionDescription& D,
+                                        unsigned IndentLevel,
+                                        raw_ostream& O) {
+  unsigned IndentLevel1 = IndentLevel + Indent1;
+
+  O.indent(IndentLevel)
+    << "for (" << D.GenTypeDeclaration()
+    << "::iterator B = " << D.GenVariableName() << ".begin(),\n";
+  O.indent(IndentLevel)
+    << "E = " << D.GenVariableName() << ".end(); B != E;) {\n";
+  O.indent(IndentLevel1) << "unsigned pos = " << D.GenVariableName()
+                         << ".getPosition(B - " << D.GenVariableName()
+                         << ".begin());\n";
+}
+
+/// EmitForwardOptionPropertyHandlingCode - Helper function used to
+/// implement EmitActionHandler. Emits code for
+/// handling the (forward) and (forward_as) option properties.
+void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D,
+                                            unsigned IndentLevel,
+                                            const std::string& NewName,
+                                            raw_ostream& O) {
+  const std::string& Name = NewName.empty()
+    ? ("-" + D.Name)
+    : NewName;
+  unsigned IndentLevel1 = IndentLevel + Indent1;
+
+  switch (D.Type) {
+  case OptionType::Switch:
+    O.indent(IndentLevel)
+      << "vec.push_back(std::make_pair(" << D.GenVariableName()
+      << ".getPosition(), \"" << Name << "\"));\n";
+    break;
+  case OptionType::Parameter:
+    O.indent(IndentLevel) << "vec.push_back(std::make_pair("
+                          << D.GenVariableName()
+                          <<".getPosition(), \"" << Name;
+
+    if (!D.isForwardNotSplit()) {
+      O << "\"));\n";
+      O.indent(IndentLevel) << "vec.push_back(std::make_pair("
+                            << D.GenVariableName() << ".getPosition(), "
+                            << D.GenVariableName() << "));\n";
+    }
+    else {
+      O << "=\" + " << D.GenVariableName() << "));\n";
+    }
+    break;
+  case OptionType::Prefix:
+    O.indent(IndentLevel) << "vec.push_back(std::make_pair("
+                          << D.GenVariableName() << ".getPosition(), \""
+                          << Name << "\" + "
+                          << D.GenVariableName() << "));\n";
+    break;
+  case OptionType::PrefixList:
+    EmitForEachListElementCycleHeader(D, IndentLevel, O);
+    O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, \""
+                           << Name << "\" + " << "*B));\n";
+    O.indent(IndentLevel1) << "++B;\n";
+
+    for (int i = 1, j = D.MultiVal; i < j; ++i) {
+      O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, *B));\n";
+      O.indent(IndentLevel1) << "++B;\n";
+    }
+
+    O.indent(IndentLevel) << "}\n";
+    break;
+  case OptionType::ParameterList:
+    EmitForEachListElementCycleHeader(D, IndentLevel, O);
+    O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, \""
+                           << Name << "\"));\n";
+
+    for (int i = 0, j = D.MultiVal; i < j; ++i) {
+      O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, *B));\n";
+      O.indent(IndentLevel1) << "++B;\n";
+    }
+
+    O.indent(IndentLevel) << "}\n";
+    break;
+  case OptionType::SwitchList:
+    EmitForEachListElementCycleHeader(D, IndentLevel, O);
+    O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, \""
+                           << Name << "\"));\n";
+    O.indent(IndentLevel1) << "++B;\n";
+    O.indent(IndentLevel) << "}\n";
+    break;
+  case OptionType::Alias:
+  default:
+    throw "Aliases are not allowed in tool option descriptions!";
+  }
+}
+
+/// ActionHandlingCallbackBase - Base class of EmitActionHandlersCallback and
+/// EmitPreprocessOptionsCallback.
+struct ActionHandlingCallbackBase
+{
+
+  void onErrorDag(const DagInit& d,
+                  unsigned IndentLevel, raw_ostream& O) const
+  {
+    O.indent(IndentLevel)
+      << "PrintError(\""
+      << (d.getNumArgs() >= 1 ? InitPtrToString(d.getArg(0)) : "Unknown error!")
+      << "\");\n";
+    O.indent(IndentLevel) << "return 1;\n";
+  }
+
+  void onWarningDag(const DagInit& d,
+                    unsigned IndentLevel, raw_ostream& O) const
+  {
+    CheckNumberOfArguments(d, 1);
+    O.indent(IndentLevel) << "llvm::errs() << \""
+                          << InitPtrToString(d.getArg(0)) << "\";\n";
+  }
+
+};
+
+/// EmitActionHandlersCallback - Emit code that handles actions. Used by
+/// EmitGenerateActionMethod() as an argument to EmitCaseConstructHandler().
+
+class EmitActionHandlersCallback;
+
+typedef void (EmitActionHandlersCallback::* EmitActionHandlersCallbackHandler)
+(const DagInit&, unsigned, raw_ostream&) const;
+
+class EmitActionHandlersCallback :
+  public ActionHandlingCallbackBase,
+  public HandlerTable<EmitActionHandlersCallbackHandler>
+{
+  typedef EmitActionHandlersCallbackHandler Handler;
+
+  const OptionDescriptions& OptDescs;
+
+  /// EmitHookInvocation - Common code for hook invocation from actions. Used by
+  /// onAppendCmd and onOutputSuffix.
+  void EmitHookInvocation(const std::string& Str,
+                          const char* BlockOpen, const char* BlockClose,
+                          unsigned IndentLevel, raw_ostream& O) const
+  {
+    StrVector Out;
+    TokenizeCmdLine(Str, Out);
+
+    for (StrVector::const_iterator B = Out.begin(), E = Out.end();
+         B != E; ++B) {
+      const std::string& cmd = *B;
+
+      O.indent(IndentLevel) << BlockOpen;
+
+      if (cmd.at(0) == '$')
+        B = SubstituteSpecialCommands(B, E,  /* IsJoin = */ true, O);
+      else
+        O << '"' << cmd << '"';
+
+      O << BlockClose;
+    }
+  }
+
+  void onAppendCmd (const DagInit& Dag,
+                    unsigned IndentLevel, raw_ostream& O) const
+  {
+    CheckNumberOfArguments(Dag, 1);
+    this->EmitHookInvocation(InitPtrToString(Dag.getArg(0)),
+                             "vec.push_back(std::make_pair(65536, ", "));\n",
+                             IndentLevel, O);
+  }
+
+  void onForward (const DagInit& Dag,
+                  unsigned IndentLevel, raw_ostream& O) const
+  {
+    CheckNumberOfArguments(Dag, 1);
+    const std::string& Name = InitPtrToString(Dag.getArg(0));
+    EmitForwardOptionPropertyHandlingCode(OptDescs.FindOption(Name),
+                                          IndentLevel, "", O);
+  }
+
+  void onForwardAs (const DagInit& Dag,
+                    unsigned IndentLevel, raw_ostream& O) const
+  {
+    CheckNumberOfArguments(Dag, 2);
+    const std::string& Name = InitPtrToString(Dag.getArg(0));
+    const std::string& NewName = InitPtrToString(Dag.getArg(1));
+    EmitForwardOptionPropertyHandlingCode(OptDescs.FindOption(Name),
+                                          IndentLevel, NewName, O);
+  }
+
+  void onForwardValue (const DagInit& Dag,
+                       unsigned IndentLevel, raw_ostream& O) const
+  {
+    CheckNumberOfArguments(Dag, 1);
+    const std::string& Name = InitPtrToString(Dag.getArg(0));
+    const OptionDescription& D = OptDescs.FindParameterListOrParameter(Name);
+
+    if (D.isSwitchList()) {
+      throw std::runtime_error
+        ("forward_value is not allowed with switch_list");
+    }
+
+    if (D.isParameter()) {
+      O.indent(IndentLevel) << "vec.push_back(std::make_pair("
+                            << D.GenVariableName() << ".getPosition(), "
+                            << D.GenVariableName() << "));\n";
+    }
+    else {
+      O.indent(IndentLevel) << "for (" << D.GenTypeDeclaration()
+                            << "::iterator B = " << D.GenVariableName()
+                            << ".begin(), \n";
+      O.indent(IndentLevel + Indent1) << " E = " << D.GenVariableName()
+                                      << ".end(); B != E; ++B)\n";
+      O.indent(IndentLevel) << "{\n";
+      O.indent(IndentLevel + Indent1)
+        << "unsigned pos = " << D.GenVariableName()
+        << ".getPosition(B - " << D.GenVariableName()
+        << ".begin());\n";
+      O.indent(IndentLevel + Indent1)
+        << "vec.push_back(std::make_pair(pos, *B));\n";
+      O.indent(IndentLevel) << "}\n";
+    }
+  }
+
+  void onForwardTransformedValue (const DagInit& Dag,
+                                  unsigned IndentLevel, raw_ostream& O) const
+  {
+    CheckNumberOfArguments(Dag, 2);
+    const std::string& Name = InitPtrToString(Dag.getArg(0));
+    const std::string& Hook = InitPtrToString(Dag.getArg(1));
+    const OptionDescription& D = OptDescs.FindParameterListOrParameter(Name);
+
+    O.indent(IndentLevel) << "vec.push_back(std::make_pair("
+                          << D.GenVariableName() << ".getPosition("
+                          << (D.isList() ? "0" : "") << "), "
+                          << "hooks::" << Hook << "(" << D.GenVariableName()
+                          << (D.isParameter() ? ".c_str()" : "") << ")));\n";
+  }
+
+  void onNoOutFile (const DagInit& Dag,
+                    unsigned IndentLevel, raw_ostream& O) const
+  {
+    CheckNumberOfArguments(Dag, 0);
+    O.indent(IndentLevel) << "no_out_file = true;\n";
+  }
+
+  void onOutputSuffix (const DagInit& Dag,
+                       unsigned IndentLevel, raw_ostream& O) const
+  {
+    CheckNumberOfArguments(Dag, 1);
+    this->EmitHookInvocation(InitPtrToString(Dag.getArg(0)),
+                             "output_suffix = ", ";\n", IndentLevel, O);
+  }
+
+  void onStopCompilation (const DagInit& Dag,
+                          unsigned IndentLevel, raw_ostream& O) const
+  {
+    O.indent(IndentLevel) << "stop_compilation = true;\n";
+  }
+
+
+  void onUnpackValues (const DagInit& Dag,
+                       unsigned IndentLevel, raw_ostream& O) const
+  {
+    throw "'unpack_values' is deprecated. "
+      "Use 'comma_separated' + 'forward_value' instead!";
+  }
+
+ public:
+
+  explicit EmitActionHandlersCallback(const OptionDescriptions& OD)
+    : OptDescs(OD)
+  {
+    if (!staticMembersInitialized_) {
+      AddHandler("error", &EmitActionHandlersCallback::onErrorDag);
+      AddHandler("warning", &EmitActionHandlersCallback::onWarningDag);
+      AddHandler("append_cmd", &EmitActionHandlersCallback::onAppendCmd);
+      AddHandler("forward", &EmitActionHandlersCallback::onForward);
+      AddHandler("forward_as", &EmitActionHandlersCallback::onForwardAs);
+      AddHandler("forward_value", &EmitActionHandlersCallback::onForwardValue);
+      AddHandler("forward_transformed_value",
+                 &EmitActionHandlersCallback::onForwardTransformedValue);
+      AddHandler("no_out_file",
+                 &EmitActionHandlersCallback::onNoOutFile);
+      AddHandler("output_suffix", &EmitActionHandlersCallback::onOutputSuffix);
+      AddHandler("stop_compilation",
+                 &EmitActionHandlersCallback::onStopCompilation);
+      AddHandler("unpack_values",
+                 &EmitActionHandlersCallback::onUnpackValues);
+
+
+      staticMembersInitialized_ = true;
+    }
+  }
+
+  void operator()(const Init* I,
+                  unsigned IndentLevel, raw_ostream& O) const
+  {
+    InvokeDagInitHandler(this, I, IndentLevel, O);
+  }
+};
+
+void EmitGenerateActionMethodHeader(const ToolDescription& D,
+                                    bool IsJoin, bool Naked,
+                                    raw_ostream& O)
+{
+  O.indent(Indent1) << "int GenerateAction(Action& Out,\n";
+
+  if (IsJoin)
+    O.indent(Indent2) << "const PathVector& inFiles,\n";
+  else
+    O.indent(Indent2) << "const sys::Path& inFile,\n";
+
+  O.indent(Indent2) << "const bool HasChildren,\n";
+  O.indent(Indent2) << "const llvm::sys::Path& TempDir,\n";
+  O.indent(Indent2) << "const InputLanguagesSet& InLangs,\n";
+  O.indent(Indent2) << "const LanguageMap& LangMap) const\n";
+  O.indent(Indent1) << "{\n";
+
+  if (!Naked) {
+    O.indent(Indent2) << "std::string cmd;\n";
+    O.indent(Indent2) << "std::string out_file;\n";
+    O.indent(Indent2)
+      << "std::vector<std::pair<unsigned, std::string> > vec;\n";
+    O.indent(Indent2) << "bool stop_compilation = !HasChildren;\n";
+    O.indent(Indent2) << "bool no_out_file = false;\n";
+    O.indent(Indent2) << "const char* output_suffix = \""
+                      << D.OutputSuffix << "\";\n";
+  }
+}
+
+// EmitGenerateActionMethod - Emit either a normal or a "join" version of the
+// Tool::GenerateAction() method.
+void EmitGenerateActionMethod (const ToolDescription& D,
+                               const OptionDescriptions& OptDescs,
+                               bool IsJoin, raw_ostream& O) {
+
+  EmitGenerateActionMethodHeader(D, IsJoin, /* Naked = */ false, O);
+
+  if (!D.CmdLine)
+    throw "Tool " + D.Name + " has no cmd_line property!";
+
+  // Process the 'command' property.
+  O << '\n';
+  EmitCmdLineVecFill(D.CmdLine, D.Name, IsJoin, Indent2, O);
+  O << '\n';
+
+  // Process the 'actions' list of this tool.
+  if (D.Actions)
+    EmitCaseConstructHandler(D.Actions, Indent2,
+                             EmitActionHandlersCallback(OptDescs),
+                             false, OptDescs, O);
+  O << '\n';
+
+  // Input file (s)
+  if (!D.InFileOption.empty()) {
+    O.indent(Indent2)
+      << "vec.push_back(std::make_pair(InputFilenames.getPosition(0), \""
+      << D.InFileOption << "\");\n";
+  }
+
+  if (IsJoin) {
+    O.indent(Indent2)
+      << "for (PathVector::const_iterator B = inFiles.begin(),\n";
+    O.indent(Indent3) << "E = inFiles.end(); B != E; ++B)\n";
+    O.indent(Indent2) << "{\n";
+    O.indent(Indent3) << "vec.push_back(std::make_pair("
+                      << "InputFilenames.getPosition(B - inFiles.begin()), "
+                      << "B->str()));\n";
+    O.indent(Indent2) << "}\n";
+  }
+  else {
+    O.indent(Indent2) << "vec.push_back(std::make_pair("
+                      << "InputFilenames.getPosition(0), inFile.str()));\n";
+  }
+
+  // Output file
+  O.indent(Indent2) << "if (!no_out_file) {\n";
+  if (!D.OutFileOption.empty())
+    O.indent(Indent3) << "vec.push_back(std::make_pair(65536, \""
+                      << D.OutFileOption << "\"));\n";
+
+  O.indent(Indent3) << "out_file = this->OutFilename("
+                    << (IsJoin ? "sys::Path(),\n" : "inFile,\n");
+  O.indent(Indent4) << "TempDir, stop_compilation, output_suffix).str();\n\n";
+  O.indent(Indent3) << "vec.push_back(std::make_pair(65536, out_file));\n";
+
+  O.indent(Indent2) << "}\n\n";
+
+  // Handle the Sink property.
+  if (D.isSink()) {
+    O.indent(Indent2) << "if (!" << SinkOptionName << ".empty()) {\n";
+    O.indent(Indent3) << "for (cl::list<std::string>::iterator B = "
+                      << SinkOptionName << ".begin(), E = " << SinkOptionName
+                      << ".end(); B != E; ++B)\n";
+    O.indent(Indent4) << "vec.push_back(std::make_pair(" << SinkOptionName
+                      << ".getPosition(B - " << SinkOptionName
+                      <<  ".begin()), *B));\n";
+    O.indent(Indent2) << "}\n";
+  }
+
+  O.indent(Indent2) << "Out.Construct(cmd, this->SortArgs(vec), "
+                    << "stop_compilation, out_file);\n";
+  O.indent(Indent2) << "return 0;\n";
+  O.indent(Indent1) << "}\n\n";
+}
+
+/// EmitGenerateActionMethods - Emit two GenerateAction() methods for
+/// a given Tool class.
+void EmitGenerateActionMethods (const ToolDescription& ToolDesc,
+                                const OptionDescriptions& OptDescs,
+                                raw_ostream& O) {
+  if (!ToolDesc.isJoin()) {
+    EmitGenerateActionMethodHeader(ToolDesc, /* IsJoin = */ true,
+                                   /* Naked = */ true, O);
+    O.indent(Indent2) << "PrintError(\"" << ToolDesc.Name
+                      << " is not a Join tool!\");\n";
+    O.indent(Indent2) << "return -1;\n";
+    O.indent(Indent1) << "}\n\n";
+  }
+  else {
+    EmitGenerateActionMethod(ToolDesc, OptDescs, true, O);
+  }
+
+  EmitGenerateActionMethod(ToolDesc, OptDescs, false, O);
+}
+
+/// EmitInOutLanguageMethods - Emit the [Input,Output]Language()
+/// methods for a given Tool class.
+void EmitInOutLanguageMethods (const ToolDescription& D, raw_ostream& O) {
+  O.indent(Indent1) << "const char** InputLanguages() const {\n";
+  O.indent(Indent2) << "return InputLanguages_;\n";
+  O.indent(Indent1) << "}\n\n";
+
+  if (D.OutLanguage.empty())
+    throw "Tool " + D.Name + " has no 'out_language' property!";
+
+  O.indent(Indent1) << "const char* OutputLanguage() const {\n";
+  O.indent(Indent2) << "return \"" << D.OutLanguage << "\";\n";
+  O.indent(Indent1) << "}\n\n";
+}
+
+/// EmitNameMethod - Emit the Name() method for a given Tool class.
+void EmitNameMethod (const ToolDescription& D, raw_ostream& O) {
+  O.indent(Indent1) << "const char* Name() const {\n";
+  O.indent(Indent2) << "return \"" << D.Name << "\";\n";
+  O.indent(Indent1) << "}\n\n";
+}
+
+/// EmitIsJoinMethod - Emit the IsJoin() method for a given Tool
+/// class.
+void EmitIsJoinMethod (const ToolDescription& D, raw_ostream& O) {
+  O.indent(Indent1) << "bool IsJoin() const {\n";
+  if (D.isJoin())
+    O.indent(Indent2) << "return true;\n";
+  else
+    O.indent(Indent2) << "return false;\n";
+  O.indent(Indent1) << "}\n\n";
+}
+
+/// EmitWorksOnEmptyCallback - Callback used by EmitWorksOnEmptyMethod in
+/// conjunction with EmitCaseConstructHandler.
+void EmitWorksOnEmptyCallback (const Init* Value,
+                               unsigned IndentLevel, raw_ostream& O) {
+  CheckBooleanConstant(Value);
+  O.indent(IndentLevel) << "return " << Value->getAsString() << ";\n";
+}
+
+/// EmitWorksOnEmptyMethod - Emit the WorksOnEmpty() method for a given Tool
+/// class.
+void EmitWorksOnEmptyMethod (const ToolDescription& D,
+                             const OptionDescriptions& OptDescs,
+                             raw_ostream& O)
+{
+  O.indent(Indent1) << "bool WorksOnEmpty() const {\n";
+  if (D.OnEmpty == 0)
+    O.indent(Indent2) << "return false;\n";
+  else
+    EmitCaseConstructHandler(D.OnEmpty, Indent2, EmitWorksOnEmptyCallback,
+                             /*EmitElseIf = */ true, OptDescs, O);
+  O.indent(Indent1) << "}\n\n";
+}
+
+/// EmitStaticMemberDefinitions - Emit static member definitions for a
+/// given Tool class.
+void EmitStaticMemberDefinitions(const ToolDescription& D, raw_ostream& O) {
+  if (D.InLanguage.empty())
+    throw "Tool " + D.Name + " has no 'in_language' property!";
+
+  O << "const char* " << D.Name << "::InputLanguages_[] = {";
+  for (StrVector::const_iterator B = D.InLanguage.begin(),
+         E = D.InLanguage.end(); B != E; ++B)
+    O << '\"' << *B << "\", ";
+  O << "0};\n\n";
+}
+
+/// EmitToolClassDefinition - Emit a Tool class definition.
+void EmitToolClassDefinition (const ToolDescription& D,
+                              const OptionDescriptions& OptDescs,
+                              raw_ostream& O) {
+  if (D.Name == "root")
+    return;
+
+  // Header
+  O << "class " << D.Name << " : public ";
+  if (D.isJoin())
+    O << "JoinTool";
+  else
+    O << "Tool";
+
+  O << " {\nprivate:\n";
+  O.indent(Indent1) << "static const char* InputLanguages_[];\n\n";
+
+  O << "public:\n";
+  EmitNameMethod(D, O);
+  EmitInOutLanguageMethods(D, O);
+  EmitIsJoinMethod(D, O);
+  EmitWorksOnEmptyMethod(D, OptDescs, O);
+  EmitGenerateActionMethods(D, OptDescs, O);
+
+  // Close class definition
+  O << "};\n";
+
+  EmitStaticMemberDefinitions(D, O);
+
+}
+
+/// EmitOptionDefinitions - Iterate over a list of option descriptions
+/// and emit registration code.
+void EmitOptionDefinitions (const OptionDescriptions& descs,
+                            bool HasSink, bool HasExterns,
+                            raw_ostream& O)
+{
+  std::vector<OptionDescription> Aliases;
+
+  // Emit static cl::Option variables.
+  for (OptionDescriptions::const_iterator B = descs.begin(),
+         E = descs.end(); B!=E; ++B) {
+    const OptionDescription& val = B->second;
+
+    if (val.Type == OptionType::Alias) {
+      Aliases.push_back(val);
+      continue;
+    }
+
+    if (val.isExtern())
+      O << "extern ";
+
+    O << val.GenTypeDeclaration() << ' '
+      << val.GenVariableName();
+
+    if (val.isExtern()) {
+      O << ";\n";
+      continue;
+    }
+
+    O << "(\"" << val.Name << "\"\n";
+
+    if (val.Type == OptionType::Prefix || val.Type == OptionType::PrefixList)
+      O << ", cl::Prefix";
+
+    if (val.isRequired()) {
+      if (val.isList() && !val.isMultiVal())
+        O << ", cl::OneOrMore";
+      else
+        O << ", cl::Required";
+    }
+
+    if (val.isOptional())
+        O << ", cl::Optional";
+
+    if (val.isOneOrMore())
+        O << ", cl::OneOrMore";
+
+    if (val.isZeroOrMore())
+        O << ", cl::ZeroOrMore";
+
+    if (val.isReallyHidden())
+      O << ", cl::ReallyHidden";
+    else if (val.isHidden())
+      O << ", cl::Hidden";
+
+    if (val.isCommaSeparated())
+      O << ", cl::CommaSeparated";
+
+    if (val.MultiVal > 1)
+      O << ", cl::multi_val(" << val.MultiVal << ')';
+
+    if (val.InitVal) {
+      const std::string& str = val.InitVal->getAsString();
+      O << ", cl::init(" << str << ')';
+    }
+
+    if (!val.Help.empty())
+      O << ", cl::desc(\"" << val.Help << "\")";
+
+    O << ");\n\n";
+  }
+
+  // Emit the aliases (they should go after all the 'proper' options).
+  for (std::vector<OptionDescription>::const_iterator
+         B = Aliases.begin(), E = Aliases.end(); B != E; ++B) {
+    const OptionDescription& val = *B;
+
+    O << val.GenTypeDeclaration() << ' '
+      << val.GenVariableName()
+      << "(\"" << val.Name << '\"';
+
+    const OptionDescription& D = descs.FindOption(val.Help);
+    O << ", cl::aliasopt(" << D.GenVariableName() << ")";
+
+    O << ", cl::desc(\"" << "An alias for -" + val.Help  << "\"));\n";
+  }
+
+  // Emit the sink option.
+  if (HasSink)
+    O << (HasExterns ? "extern cl" : "cl")
+      << "::list<std::string> " << SinkOptionName
+      << (HasExterns ? ";\n" : "(cl::Sink);\n");
+
+  O << '\n';
+}
+
+/// EmitPreprocessOptionsCallback - Helper function passed to
+/// EmitCaseConstructHandler() by EmitPreprocessOptions().
+
+class EmitPreprocessOptionsCallback;
+
+typedef void
+(EmitPreprocessOptionsCallback::* EmitPreprocessOptionsCallbackHandler)
+(const DagInit&, unsigned, raw_ostream&) const;
+
+class EmitPreprocessOptionsCallback :
+  public ActionHandlingCallbackBase,
+  public HandlerTable<EmitPreprocessOptionsCallbackHandler>
+{
+  typedef EmitPreprocessOptionsCallbackHandler Handler;
+  typedef void
+  (EmitPreprocessOptionsCallback::* HandlerImpl)
+  (const Init*, unsigned, raw_ostream&) const;
+
+  const OptionDescriptions& OptDescs_;
+
+  void onListOrDag(const DagInit& d, HandlerImpl h,
+                   unsigned IndentLevel, raw_ostream& O) const
+  {
+    CheckNumberOfArguments(d, 1);
+    const Init* I = d.getArg(0);
+
+    // If I is a list, apply h to each element.
+    if (typeid(*I) == typeid(ListInit)) {
+      const ListInit& L = *static_cast<const ListInit*>(I);
+      for (ListInit::const_iterator B = L.begin(), E = L.end(); B != E; ++B)
+        ((this)->*(h))(*B, IndentLevel, O);
+    }
+    // Otherwise, apply h to I.
+    else {
+      ((this)->*(h))(I, IndentLevel, O);
+    }
+  }
+
+  void onUnsetOptionImpl(const Init* I,
+                         unsigned IndentLevel, raw_ostream& O) const
+  {
+    const std::string& OptName = InitPtrToString(I);
+    const OptionDescription& OptDesc = OptDescs_.FindOption(OptName);
+
+    if (OptDesc.isSwitch()) {
+      O.indent(IndentLevel) << OptDesc.GenVariableName() << " = false;\n";
+    }
+    else if (OptDesc.isParameter()) {
+      O.indent(IndentLevel) << OptDesc.GenVariableName() << " = \"\";\n";
+    }
+    else if (OptDesc.isList()) {
+      O.indent(IndentLevel) << OptDesc.GenVariableName() << ".clear();\n";
+    }
+    else {
+      throw "Can't apply 'unset_option' to alias option '" + OptName + "'!";
+    }
+  }
+
+  void onUnsetOption(const DagInit& d,
+                     unsigned IndentLevel, raw_ostream& O) const
+  {
+    this->onListOrDag(d, &EmitPreprocessOptionsCallback::onUnsetOptionImpl,
+                      IndentLevel, O);
+  }
+
+  void onSetOptionImpl(const DagInit& d,
+                       unsigned IndentLevel, raw_ostream& O) const {
+    CheckNumberOfArguments(d, 2);
+    const std::string& OptName = InitPtrToString(d.getArg(0));
+    const Init* Value = d.getArg(1);
+    const OptionDescription& OptDesc = OptDescs_.FindOption(OptName);
+
+    if (OptDesc.isList()) {
+      const ListInit& List = InitPtrToList(Value);
+
+      O.indent(IndentLevel) << OptDesc.GenVariableName() << ".clear();\n";
+      for (ListInit::const_iterator B = List.begin(), E = List.end();
+           B != E; ++B) {
+        const Init* CurElem = *B;
+        if (OptDesc.isSwitchList())
+          CheckBooleanConstant(CurElem);
+
+        O.indent(IndentLevel)
+          << OptDesc.GenVariableName() << ".push_back(\""
+          << (OptDesc.isSwitchList() ? CurElem->getAsString()
+              : InitPtrToString(CurElem))
+          << "\");\n";
+      }
+    }
+    else if (OptDesc.isSwitch()) {
+      CheckBooleanConstant(Value);
+      O.indent(IndentLevel) << OptDesc.GenVariableName()
+                            << " = " << Value->getAsString() << ";\n";
+    }
+    else if (OptDesc.isParameter()) {
+      const std::string& Str = InitPtrToString(Value);
+      O.indent(IndentLevel) << OptDesc.GenVariableName()
+                            << " = \"" << Str << "\";\n";
+    }
+    else {
+      throw "Can't apply 'set_option' to alias option -" + OptName + " !";
+    }
+  }
+
+  void onSetSwitch(const Init* I,
+                   unsigned IndentLevel, raw_ostream& O) const {
+    const std::string& OptName = InitPtrToString(I);
+    const OptionDescription& OptDesc = OptDescs_.FindOption(OptName);
+
+    if (OptDesc.isSwitch())
+      O.indent(IndentLevel) << OptDesc.GenVariableName() << " = true;\n";
+    else
+      throw "set_option: -" + OptName + " is not a switch option!";
+  }
+
+  void onSetOption(const DagInit& d,
+                   unsigned IndentLevel, raw_ostream& O) const
+  {
+    CheckNumberOfArguments(d, 1);
+
+    // Two arguments: (set_option "parameter", VALUE), where VALUE can be a
+    // boolean, a string or a string list.
+    if (d.getNumArgs() > 1)
+      this->onSetOptionImpl(d, IndentLevel, O);
+    // One argument: (set_option "switch")
+    // or (set_option ["switch1", "switch2", ...])
+    else
+      this->onListOrDag(d, &EmitPreprocessOptionsCallback::onSetSwitch,
+                        IndentLevel, O);
+  }
+
+public:
+
+  EmitPreprocessOptionsCallback(const OptionDescriptions& OptDescs)
+  : OptDescs_(OptDescs)
+  {
+    if (!staticMembersInitialized_) {
+      AddHandler("error", &EmitPreprocessOptionsCallback::onErrorDag);
+      AddHandler("warning", &EmitPreprocessOptionsCallback::onWarningDag);
+      AddHandler("unset_option", &EmitPreprocessOptionsCallback::onUnsetOption);
+      AddHandler("set_option", &EmitPreprocessOptionsCallback::onSetOption);
+
+      staticMembersInitialized_ = true;
+    }
+  }
+
+  void operator()(const Init* I,
+                  unsigned IndentLevel, raw_ostream& O) const
+  {
+    InvokeDagInitHandler(this, I, IndentLevel, O);
+  }
+
+};
+
+/// EmitPreprocessOptions - Emit the PreprocessOptionsLocal() function.
+void EmitPreprocessOptions (const RecordKeeper& Records,
+                            const OptionDescriptions& OptDecs, raw_ostream& O)
+{
+  O << "int PreprocessOptionsLocal() {\n";
+
+  const RecordVector& OptionPreprocessors =
+    Records.getAllDerivedDefinitions("OptionPreprocessor");
+
+  for (RecordVector::const_iterator B = OptionPreprocessors.begin(),
+         E = OptionPreprocessors.end(); B!=E; ++B) {
+    DagInit* Case = (*B)->getValueAsDag("preprocessor");
+    EmitCaseConstructHandler(Case, Indent1,
+                             EmitPreprocessOptionsCallback(OptDecs),
+                             false, OptDecs, O);
+  }
+
+  O << '\n';
+  O.indent(Indent1) << "return 0;\n";
+  O << "}\n\n";
+}
+
+/// EmitPopulateLanguageMap - Emit the PopulateLanguageMapLocal() function.
+void EmitPopulateLanguageMap (const RecordKeeper& Records, raw_ostream& O)
+{
+  O << "int PopulateLanguageMapLocal(LanguageMap& langMap) {\n";
+
+  // Get the relevant field out of RecordKeeper
+  const Record* LangMapRecord = Records.getDef("LanguageMap");
+
+  // It is allowed for a plugin to have no language map.
+  if (LangMapRecord) {
+
+    ListInit* LangsToSuffixesList = LangMapRecord->getValueAsListInit("map");
+    if (!LangsToSuffixesList)
+      throw "Error in the language map definition!";
+
+    for (unsigned i = 0; i < LangsToSuffixesList->size(); ++i) {
+      const Record* LangToSuffixes = LangsToSuffixesList->getElementAsRecord(i);
+
+      const std::string& Lang = LangToSuffixes->getValueAsString("lang");
+      const ListInit* Suffixes = LangToSuffixes->getValueAsListInit("suffixes");
+
+      for (unsigned i = 0; i < Suffixes->size(); ++i)
+        O.indent(Indent1) << "langMap[\""
+                          << InitPtrToString(Suffixes->getElement(i))
+                          << "\"] = \"" << Lang << "\";\n";
+    }
+  }
+
+  O << '\n';
+  O.indent(Indent1) << "return 0;\n";
+  O << "}\n\n";
+}
+
+/// IncDecWeight - Helper function passed to EmitCaseConstructHandler()
+/// by EmitEdgeClass().
+void IncDecWeight (const Init* i, unsigned IndentLevel,
+                   raw_ostream& O) {
+  const DagInit& d = InitPtrToDag(i);
+  const std::string& OpName = GetOperatorName(d);
+
+  if (OpName == "inc_weight") {
+    O.indent(IndentLevel) << "ret += ";
+  }
+  else if (OpName == "dec_weight") {
+    O.indent(IndentLevel) << "ret -= ";
+  }
+  else if (OpName == "error") {
+    // TODO: fix this
+    CheckNumberOfArguments(d, 1);
+    O.indent(IndentLevel) << "PrintError(\""
+                          << InitPtrToString(d.getArg(0))
+                          << "\");\n";
+    O.indent(IndentLevel) << "return -1;\n";
+    return;
+  }
+  else {
+    throw "Unknown operator in edge properties list: '" + OpName + "'!"
+      "\nOnly 'inc_weight', 'dec_weight' and 'error' are allowed.";
+  }
+
+  if (d.getNumArgs() > 0)
+    O << InitPtrToInt(d.getArg(0)) << ";\n";
+  else
+    O << "2;\n";
+
+}
+
+/// EmitEdgeClass - Emit a single Edge# class.
+void EmitEdgeClass (unsigned N, const std::string& Target,
+                    DagInit* Case, const OptionDescriptions& OptDescs,
+                    raw_ostream& O) {
+
+  // Class constructor.
+  O << "class Edge" << N << ": public Edge {\n"
+    << "public:\n";
+  O.indent(Indent1) << "Edge" << N << "() : Edge(\"" << Target
+                    << "\") {}\n\n";
+
+  // Function Weight().
+  O.indent(Indent1)
+    << "unsigned Weight(const InputLanguagesSet& InLangs) const {\n";
+  O.indent(Indent2) << "unsigned ret = 0;\n";
+
+  // Handle the 'case' construct.
+  EmitCaseConstructHandler(Case, Indent2, IncDecWeight, false, OptDescs, O);
+
+  O.indent(Indent2) << "return ret;\n";
+  O.indent(Indent1) << "}\n\n};\n\n";
+}
+
+/// EmitEdgeClasses - Emit Edge* classes that represent graph edges.
+void EmitEdgeClasses (const RecordVector& EdgeVector,
+                      const OptionDescriptions& OptDescs,
+                      raw_ostream& O) {
+  int i = 0;
+  for (RecordVector::const_iterator B = EdgeVector.begin(),
+         E = EdgeVector.end(); B != E; ++B) {
+    const Record* Edge = *B;
+    const std::string& NodeB = Edge->getValueAsString("b");
+    DagInit& Weight = *Edge->getValueAsDag("weight");
+
+    if (!IsDagEmpty(Weight))
+      EmitEdgeClass(i, NodeB, &Weight, OptDescs, O);
+    ++i;
+  }
+}
+
+/// EmitPopulateCompilationGraph - Emit the PopulateCompilationGraphLocal()
+/// function.
+void EmitPopulateCompilationGraph (const RecordVector& EdgeVector,
+                                   const ToolDescriptions& ToolDescs,
+                                   raw_ostream& O)
+{
+  O << "int PopulateCompilationGraphLocal(CompilationGraph& G) {\n";
+
+  for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
+         E = ToolDescs.end(); B != E; ++B)
+    O.indent(Indent1) << "G.insertNode(new " << (*B)->Name << "());\n";
+
+  O << '\n';
+
+  // Insert edges.
+
+  int i = 0;
+  for (RecordVector::const_iterator B = EdgeVector.begin(),
+         E = EdgeVector.end(); B != E; ++B) {
+    const Record* Edge = *B;
+    const std::string& NodeA = Edge->getValueAsString("a");
+    const std::string& NodeB = Edge->getValueAsString("b");
+    DagInit& Weight = *Edge->getValueAsDag("weight");
+
+    O.indent(Indent1) << "if (int ret = G.insertEdge(\"" << NodeA << "\", ";
+
+    if (IsDagEmpty(Weight))
+      O << "new SimpleEdge(\"" << NodeB << "\")";
+    else
+      O << "new Edge" << i << "()";
+
+    O << "))\n";
+    O.indent(Indent2) << "return ret;\n";
+
+    ++i;
+  }
+
+  O << '\n';
+  O.indent(Indent1) << "return 0;\n";
+  O << "}\n\n";
+}
+
+/// HookInfo - Information about the hook type and number of arguments.
+struct HookInfo {
+
+  // A hook can either have a single parameter of type std::vector<std::string>,
+  // or NumArgs parameters of type const char*.
+  enum HookType { ListHook, ArgHook };
+
+  HookType Type;
+  unsigned NumArgs;
+
+  HookInfo() : Type(ArgHook), NumArgs(1)
+  {}
+
+  HookInfo(HookType T) : Type(T), NumArgs(1)
+  {}
+
+  HookInfo(unsigned N) : Type(ArgHook), NumArgs(N)
+  {}
+};
+
+typedef llvm::StringMap<HookInfo> HookInfoMap;
+
+/// ExtractHookNames - Extract the hook names from all instances of
+/// $CALL(HookName) in the provided command line string/action. Helper
+/// function used by FillInHookNames().
+class ExtractHookNames {
+  HookInfoMap& HookNames_;
+  const OptionDescriptions& OptDescs_;
+public:
+  ExtractHookNames(HookInfoMap& HookNames, const OptionDescriptions& OptDescs)
+    : HookNames_(HookNames), OptDescs_(OptDescs)
+  {}
+
+  void onAction (const DagInit& Dag) {
+    const std::string& Name = GetOperatorName(Dag);
+
+    if (Name == "forward_transformed_value") {
+      CheckNumberOfArguments(Dag, 2);
+      const std::string& OptName = InitPtrToString(Dag.getArg(0));
+      const std::string& HookName = InitPtrToString(Dag.getArg(1));
+      const OptionDescription& D =
+        OptDescs_.FindParameterListOrParameter(OptName);
+
+      HookNames_[HookName] = HookInfo(D.isList() ? HookInfo::ListHook
+                                      : HookInfo::ArgHook);
+    }
+    else if (Name == "append_cmd" || Name == "output_suffix") {
+      CheckNumberOfArguments(Dag, 1);
+      this->onCmdLine(InitPtrToString(Dag.getArg(0)));
+    }
+  }
+
+  void onCmdLine(const std::string& Cmd) {
+    StrVector cmds;
+    TokenizeCmdLine(Cmd, cmds);
+
+    for (StrVector::const_iterator B = cmds.begin(), E = cmds.end();
+         B != E; ++B) {
+      const std::string& cmd = *B;
+
+      if (cmd == "$CALL") {
+        unsigned NumArgs = 0;
+        CheckedIncrement(B, E, "Syntax error in $CALL invocation!");
+        const std::string& HookName = *B;
+
+        if (HookName.at(0) == ')')
+          throw "$CALL invoked with no arguments!";
+
+        while (++B != E && B->at(0) != ')') {
+          ++NumArgs;
+        }
+
+        HookInfoMap::const_iterator H = HookNames_.find(HookName);
+
+        if (H != HookNames_.end() && H->second.NumArgs != NumArgs &&
+            H->second.Type != HookInfo::ArgHook)
+          throw "Overloading of hooks is not allowed. Overloaded hook: "
+            + HookName;
+        else
+          HookNames_[HookName] = HookInfo(NumArgs);
+      }
+    }
+  }
+
+  void operator()(const Init* Arg) {
+
+    // We're invoked on an action (either a dag or a dag list).
+    if (typeid(*Arg) == typeid(DagInit)) {
+      const DagInit& Dag = InitPtrToDag(Arg);
+      this->onAction(Dag);
+      return;
+    }
+    else if (typeid(*Arg) == typeid(ListInit)) {
+      const ListInit& List = InitPtrToList(Arg);
+      for (ListInit::const_iterator B = List.begin(), E = List.end(); B != E;
+           ++B) {
+        const DagInit& Dag = InitPtrToDag(*B);
+        this->onAction(Dag);
+      }
+      return;
+    }
+
+    // We're invoked on a command line.
+    this->onCmdLine(InitPtrToString(Arg));
+  }
+
+  void operator()(const DagInit* Test, unsigned, bool) {
+    this->operator()(Test);
+  }
+  void operator()(const Init* Statement, unsigned) {
+    this->operator()(Statement);
+  }
+};
+
+/// FillInHookNames - Actually extract the hook names from all command
+/// line strings. Helper function used by EmitHookDeclarations().
+void FillInHookNames(const ToolDescriptions& ToolDescs,
+                     const OptionDescriptions& OptDescs,
+                     HookInfoMap& HookNames)
+{
+  // For all tool descriptions:
+  for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
+         E = ToolDescs.end(); B != E; ++B) {
+    const ToolDescription& D = *(*B);
+
+    // Look for 'forward_transformed_value' in 'actions'.
+    if (D.Actions)
+      WalkCase(D.Actions, Id(), ExtractHookNames(HookNames, OptDescs));
+
+    // Look for hook invocations in 'cmd_line'.
+    if (!D.CmdLine)
+      continue;
+    if (dynamic_cast<StringInit*>(D.CmdLine))
+      // This is a string.
+      ExtractHookNames(HookNames, OptDescs).operator()(D.CmdLine);
+    else
+      // This is a 'case' construct.
+      WalkCase(D.CmdLine, Id(), ExtractHookNames(HookNames, OptDescs));
+  }
+}
+
+/// EmitHookDeclarations - Parse CmdLine fields of all the tool
+/// property records and emit hook function declaration for each
+/// instance of $CALL(HookName).
+void EmitHookDeclarations(const ToolDescriptions& ToolDescs,
+                          const OptionDescriptions& OptDescs, raw_ostream& O) {
+  HookInfoMap HookNames;
+
+  FillInHookNames(ToolDescs, OptDescs, HookNames);
+  if (HookNames.empty())
+    return;
+
+  O << "namespace hooks {\n";
+  for (HookInfoMap::const_iterator B = HookNames.begin(),
+         E = HookNames.end(); B != E; ++B) {
+    const char* HookName = B->first();
+    const HookInfo& Info = B->second;
+
+    O.indent(Indent1) << "std::string " << HookName << "(";
+
+    if (Info.Type == HookInfo::ArgHook) {
+      for (unsigned i = 0, j = Info.NumArgs; i < j; ++i) {
+        O << "const char* Arg" << i << (i+1 == j ? "" : ", ");
+      }
+    }
+    else {
+      O << "const std::vector<std::string>& Arg";
+    }
+
+    O <<");\n";
+  }
+  O << "}\n\n";
+}
+
+/// EmitRegisterPlugin - Emit code to register this plugin.
+void EmitRegisterPlugin(int Priority, raw_ostream& O) {
+  O << "struct Plugin : public llvmc::BasePlugin {\n\n";
+  O.indent(Indent1) << "int Priority() const { return "
+                    << Priority << "; }\n\n";
+  O.indent(Indent1) << "int PreprocessOptions() const\n";
+  O.indent(Indent1) << "{ return PreprocessOptionsLocal(); }\n\n";
+  O.indent(Indent1) << "int PopulateLanguageMap(LanguageMap& langMap) const\n";
+  O.indent(Indent1) << "{ return PopulateLanguageMapLocal(langMap); }\n\n";
+  O.indent(Indent1)
+    << "int PopulateCompilationGraph(CompilationGraph& graph) const\n";
+  O.indent(Indent1) << "{ return PopulateCompilationGraphLocal(graph); }\n"
+                    << "};\n\n"
+                    << "static llvmc::RegisterPlugin<Plugin> RP;\n\n";
+}
+
+/// EmitIncludes - Emit necessary #include directives and some
+/// additional declarations.
+void EmitIncludes(raw_ostream& O) {
+  O << "#include \"llvm/CompilerDriver/BuiltinOptions.h\"\n"
+    << "#include \"llvm/CompilerDriver/CompilationGraph.h\"\n"
+    << "#include \"llvm/CompilerDriver/Error.h\"\n"
+    << "#include \"llvm/CompilerDriver/ForceLinkageMacros.h\"\n"
+    << "#include \"llvm/CompilerDriver/Plugin.h\"\n"
+    << "#include \"llvm/CompilerDriver/Tool.h\"\n\n"
+
+    << "#include \"llvm/Support/CommandLine.h\"\n"
+    << "#include \"llvm/Support/raw_ostream.h\"\n\n"
+
+    << "#include <algorithm>\n"
+    << "#include <cstdlib>\n"
+    << "#include <iterator>\n"
+    << "#include <stdexcept>\n\n"
+
+    << "using namespace llvm;\n"
+    << "using namespace llvmc;\n\n"
+
+    << "extern cl::opt<std::string> OutputFilename;\n\n"
+
+    << "inline const char* checkCString(const char* s)\n"
+    << "{ return s == NULL ? \"\" : s; }\n\n";
+}
+
+
+/// PluginData - Holds all information about a plugin.
+struct PluginData {
+  OptionDescriptions OptDescs;
+  bool HasSink;
+  bool HasExterns;
+  ToolDescriptions ToolDescs;
+  RecordVector Edges;
+  int Priority;
+};
+
+/// HasSink - Go through the list of tool descriptions and check if
+/// there are any with the 'sink' property set.
+bool HasSink(const ToolDescriptions& ToolDescs) {
+  for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
+         E = ToolDescs.end(); B != E; ++B)
+    if ((*B)->isSink())
+      return true;
+
+  return false;
+}
+
+/// HasExterns - Go through the list of option descriptions and check
+/// if there are any external options.
+bool HasExterns(const OptionDescriptions& OptDescs) {
+ for (OptionDescriptions::const_iterator B = OptDescs.begin(),
+         E = OptDescs.end(); B != E; ++B)
+    if (B->second.isExtern())
+      return true;
+
+  return false;
+}
+
+/// CollectPluginData - Collect tool and option properties,
+/// compilation graph edges and plugin priority from the parse tree.
+void CollectPluginData (const RecordKeeper& Records, PluginData& Data) {
+  // Collect option properties.
+  const RecordVector& OptionLists =
+    Records.getAllDerivedDefinitions("OptionList");
+  CollectOptionDescriptions(OptionLists.begin(), OptionLists.end(),
+                            Data.OptDescs);
+
+  // Collect tool properties.
+  const RecordVector& Tools = Records.getAllDerivedDefinitions("Tool");
+  CollectToolDescriptions(Tools.begin(), Tools.end(), Data.ToolDescs);
+  Data.HasSink = HasSink(Data.ToolDescs);
+  Data.HasExterns = HasExterns(Data.OptDescs);
+
+  // Collect compilation graph edges.
+  const RecordVector& CompilationGraphs =
+    Records.getAllDerivedDefinitions("CompilationGraph");
+  FillInEdgeVector(CompilationGraphs.begin(), CompilationGraphs.end(),
+                   Data.Edges);
+
+  // Calculate the priority of this plugin.
+  const RecordVector& Priorities =
+    Records.getAllDerivedDefinitions("PluginPriority");
+  Data.Priority = CalculatePriority(Priorities.begin(), Priorities.end());
+}
+
+/// CheckPluginData - Perform some sanity checks on the collected data.
+void CheckPluginData(PluginData& Data) {
+  // Filter out all tools not mentioned in the compilation graph.
+  FilterNotInGraph(Data.Edges, Data.ToolDescs);
+
+  // Typecheck the compilation graph.
+  TypecheckGraph(Data.Edges, Data.ToolDescs);
+
+  // Check that there are no options without side effects (specified
+  // only in the OptionList).
+  CheckForSuperfluousOptions(Data.Edges, Data.ToolDescs, Data.OptDescs);
+}
+
+void EmitPluginCode(const PluginData& Data, raw_ostream& O) {
+  // Emit file header.
+  EmitIncludes(O);
+
+  // Emit global option registration code.
+  EmitOptionDefinitions(Data.OptDescs, Data.HasSink, Data.HasExterns, O);
+
+  // Emit hook declarations.
+  EmitHookDeclarations(Data.ToolDescs, Data.OptDescs, O);
+
+  O << "namespace {\n\n";
+
+  // Emit PreprocessOptionsLocal() function.
+  EmitPreprocessOptions(Records, Data.OptDescs, O);
+
+  // Emit PopulateLanguageMapLocal() function
+  // (language map maps from file extensions to language names).
+  EmitPopulateLanguageMap(Records, O);
+
+  // Emit Tool classes.
+  for (ToolDescriptions::const_iterator B = Data.ToolDescs.begin(),
+         E = Data.ToolDescs.end(); B!=E; ++B)
+    EmitToolClassDefinition(*(*B), Data.OptDescs, O);
+
+  // Emit Edge# classes.
+  EmitEdgeClasses(Data.Edges, Data.OptDescs, O);
+
+  // Emit PopulateCompilationGraphLocal() function.
+  EmitPopulateCompilationGraph(Data.Edges, Data.ToolDescs, O);
+
+  // Emit code for plugin registration.
+  EmitRegisterPlugin(Data.Priority, O);
+
+  O << "} // End anonymous namespace.\n\n";
+
+  // Force linkage magic.
+  O << "namespace llvmc {\n";
+  O << "LLVMC_FORCE_LINKAGE_DECL(LLVMC_PLUGIN_NAME) {}\n";
+  O << "}\n";
+
+  // EOF
+}
+
+
+// End of anonymous namespace
+}
+
+/// run - The back-end entry point.
+void LLVMCConfigurationEmitter::run (raw_ostream &O) {
+  try {
+  PluginData Data;
+
+  CollectPluginData(Records, Data);
+  CheckPluginData(Data);
+
+  this->EmitSourceFileHeader("LLVMC Configuration Library", O);
+  EmitPluginCode(Data, O);
+
+  } catch (std::exception& Error) {
+    throw Error.what() + std::string(" - usually this means a syntax error.");
+  }
+}
diff --git a/src/LLVM/utils/TableGen/LLVMCConfigurationEmitter.h b/src/LLVM/utils/TableGen/LLVMCConfigurationEmitter.h
new file mode 100644
index 0000000..b37b83f
--- /dev/null
+++ b/src/LLVM/utils/TableGen/LLVMCConfigurationEmitter.h
@@ -0,0 +1,32 @@
+//===- LLVMCConfigurationEmitter.cpp - Generate LLVMCC config ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open
+// Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend is responsible for emitting LLVMCC configuration code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_UTILS_TABLEGEN_LLVMCCONF_EMITTER_H
+#define LLVM_UTILS_TABLEGEN_LLVMCCONF_EMITTER_H
+
+#include "TableGenBackend.h"
+
+namespace llvm {
+
+  /// LLVMCConfigurationEmitter - TableGen backend that generates
+  /// configuration code for LLVMC.
+  class LLVMCConfigurationEmitter : public TableGenBackend {
+  public:
+    explicit LLVMCConfigurationEmitter(RecordKeeper&) {}
+
+    // run - Output the asmwriter, returning true on failure.
+    void run(raw_ostream &o);
+  };
+}
+
+#endif //LLVM_UTILS_TABLEGEN_LLVMCCONF_EMITTER_H
diff --git a/src/LLVM/utils/TableGen/Makefile b/src/LLVM/utils/TableGen/Makefile
new file mode 100644
index 0000000..f27cd99
--- /dev/null
+++ b/src/LLVM/utils/TableGen/Makefile
@@ -0,0 +1,20 @@
+##===- utils/TableGen/Makefile -----------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+TOOLNAME = tblgen
+USEDLIBS = LLVMSupport.a LLVMSystem.a
+REQUIRES_EH := 1
+REQUIRES_RTTI := 1
+
+# This tool has no plugins, optimize startup time.
+TOOL_NO_EXPORTS = 1
+
+include $(LEVEL)/Makefile.common
+
diff --git a/src/LLVM/utils/TableGen/NeonEmitter.cpp b/src/LLVM/utils/TableGen/NeonEmitter.cpp
new file mode 100644
index 0000000..0a12f37
--- /dev/null
+++ b/src/LLVM/utils/TableGen/NeonEmitter.cpp
@@ -0,0 +1,1207 @@
+//===- NeonEmitter.cpp - Generate arm_neon.h for use with clang -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend is responsible for emitting arm_neon.h, which includes
+// a declaration and definition of each function specified by the ARM NEON 
+// compiler interface.  See ARM document DUI0348B.
+//
+// Each NEON instruction is implemented in terms of 1 or more functions which
+// are suffixed with the element type of the input vectors.  Functions may be 
+// implemented in terms of generic vector operations such as +, *, -, etc. or
+// by calling a __builtin_-prefixed function which will be handled by clang's
+// CodeGen library.
+//
+// Additional validation code can be generated by this file when runHeader() is
+// called, rather than the normal run() entry point.
+//
+//===----------------------------------------------------------------------===//
+
+#include "NeonEmitter.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
+#include <string>
+
+using namespace llvm;
+
+/// ParseTypes - break down a string such as "fQf" into a vector of StringRefs,
+/// which each StringRef representing a single type declared in the string.
+/// for "fQf" we would end up with 2 StringRefs, "f", and "Qf", representing
+/// 2xfloat and 4xfloat respectively.
+static void ParseTypes(Record *r, std::string &s,
+                       SmallVectorImpl<StringRef> &TV) {
+  const char *data = s.data();
+  int len = 0;
+  
+  for (unsigned i = 0, e = s.size(); i != e; ++i, ++len) {
+    if (data[len] == 'P' || data[len] == 'Q' || data[len] == 'U')
+      continue;
+    
+    switch (data[len]) {
+      case 'c':
+      case 's':
+      case 'i':
+      case 'l':
+      case 'h':
+      case 'f':
+        break;
+      default:
+        throw TGError(r->getLoc(),
+                      "Unexpected letter: " + std::string(data + len, 1));
+        break;
+    }
+    TV.push_back(StringRef(data, len + 1));
+    data += len + 1;
+    len = -1;
+  }
+}
+
+/// Widen - Convert a type code into the next wider type.  char -> short,
+/// short -> int, etc.
+static char Widen(const char t) {
+  switch (t) {
+    case 'c':
+      return 's';
+    case 's':
+      return 'i';
+    case 'i':
+      return 'l';
+    default: throw "unhandled type in widen!";
+  }
+  return '\0';
+}
+
+/// Narrow - Convert a type code into the next smaller type.  short -> char,
+/// float -> half float, etc.
+static char Narrow(const char t) {
+  switch (t) {
+    case 's':
+      return 'c';
+    case 'i':
+      return 's';
+    case 'l':
+      return 'i';
+    case 'f':
+      return 'h';
+    default: throw "unhandled type in widen!";
+  }
+  return '\0';
+}
+
+/// For a particular StringRef, return the base type code, and whether it has
+/// the quad-vector, polynomial, or unsigned modifiers set.
+static char ClassifyType(StringRef ty, bool &quad, bool &poly, bool &usgn) {
+  unsigned off = 0;
+  
+  // remember quad.
+  if (ty[off] == 'Q') {
+    quad = true;
+    ++off;
+  }
+  
+  // remember poly.
+  if (ty[off] == 'P') {
+    poly = true;
+    ++off;
+  }
+  
+  // remember unsigned.
+  if (ty[off] == 'U') {
+    usgn = true;
+    ++off;
+  }
+  
+  // base type to get the type string for.
+  return ty[off];
+}
+
+/// ModType - Transform a type code and its modifiers based on a mod code. The
+/// mod code definitions may be found at the top of arm_neon.td.
+static char ModType(const char mod, char type, bool &quad, bool &poly,
+                    bool &usgn, bool &scal, bool &cnst, bool &pntr) {
+  switch (mod) {
+    case 't':
+      if (poly) {
+        poly = false;
+        usgn = true;
+      }
+      break;
+    case 'u':
+      usgn = true;
+    case 'x':
+      poly = false;
+      if (type == 'f')
+        type = 'i';
+      break;
+    case 'f':
+      if (type == 'h')
+        quad = true;
+      type = 'f';
+      usgn = false;
+      break;
+    case 'g':
+      quad = false;
+      break;
+    case 'w':
+      type = Widen(type);
+      quad = true;
+      break;
+    case 'n':
+      type = Widen(type);
+      break;
+    case 'l':
+      type = 'l';
+      scal = true;
+      usgn = true;
+      break;
+    case 's':
+    case 'a':
+      scal = true;
+      break;
+    case 'k':
+      quad = true;
+      break;
+    case 'c':
+      cnst = true;
+    case 'p':
+      pntr = true;
+      scal = true;
+      break;
+    case 'h':
+      type = Narrow(type);
+      if (type == 'h')
+        quad = false;
+      break;
+    case 'e':
+      type = Narrow(type);
+      usgn = true;
+      break;
+    default:
+      break;
+  }
+  return type;
+}
+
+/// TypeString - for a modifier and type, generate the name of the typedef for
+/// that type.  If generic is true, emit the generic vector type rather than
+/// the public NEON type. QUc -> uint8x8_t / __neon_uint8x8_t.
+static std::string TypeString(const char mod, StringRef typestr,
+                              bool generic = false) {
+  bool quad = false;
+  bool poly = false;
+  bool usgn = false;
+  bool scal = false;
+  bool cnst = false;
+  bool pntr = false;
+  
+  if (mod == 'v')
+    return "void";
+  if (mod == 'i')
+    return "int";
+  
+  // base type to get the type string for.
+  char type = ClassifyType(typestr, quad, poly, usgn);
+  
+  // Based on the modifying character, change the type and width if necessary.
+  type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr);
+  
+  SmallString<128> s;
+  
+  if (generic)
+    s += "__neon_";
+  
+  if (usgn)
+    s.push_back('u');
+  
+  switch (type) {
+    case 'c':
+      s += poly ? "poly8" : "int8";
+      if (scal)
+        break;
+      s += quad ? "x16" : "x8";
+      break;
+    case 's':
+      s += poly ? "poly16" : "int16";
+      if (scal)
+        break;
+      s += quad ? "x8" : "x4";
+      break;
+    case 'i':
+      s += "int32";
+      if (scal)
+        break;
+      s += quad ? "x4" : "x2";
+      break;
+    case 'l':
+      s += "int64";
+      if (scal)
+        break;
+      s += quad ? "x2" : "x1";
+      break;
+    case 'h':
+      s += "float16";
+      if (scal)
+        break;
+      s += quad ? "x8" : "x4";
+      break;
+    case 'f':
+      s += "float32";
+      if (scal)
+        break;
+      s += quad ? "x4" : "x2";
+      break;
+    default:
+      throw "unhandled type!";
+      break;
+  }
+
+  if (mod == '2')
+    s += "x2";
+  if (mod == '3')
+    s += "x3";
+  if (mod == '4')
+    s += "x4";
+  
+  // Append _t, finishing the type string typedef type.
+  s += "_t";
+  
+  if (cnst)
+    s += " const";
+  
+  if (pntr)
+    s += " *";
+  
+  return s.str();
+}
+
+/// BuiltinTypeString - for a modifier and type, generate the clang
+/// BuiltinsARM.def prototype code for the function.  See the top of clang's
+/// Builtins.def for a description of the type strings.
+static std::string BuiltinTypeString(const char mod, StringRef typestr,
+                                     ClassKind ck, bool ret) {
+  bool quad = false;
+  bool poly = false;
+  bool usgn = false;
+  bool scal = false;
+  bool cnst = false;
+  bool pntr = false;
+  
+  if (mod == 'v')
+    return "v";
+  if (mod == 'i')
+    return "i";
+  
+  // base type to get the type string for.
+  char type = ClassifyType(typestr, quad, poly, usgn);
+  
+  // Based on the modifying character, change the type and width if necessary.
+  type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr);
+
+  if (pntr) {
+    usgn = false;
+    poly = false;
+    type = 'v';
+  }
+  if (type == 'h') {
+    type = 's';
+    usgn = true;
+  }
+  usgn = usgn | poly | ((ck == ClassI || ck == ClassW) && scal && type != 'f');
+
+  if (scal) {
+    SmallString<128> s;
+
+    if (usgn)
+      s.push_back('U');
+    
+    if (type == 'l')
+      s += "LLi";
+    else
+      s.push_back(type);
+ 
+    if (cnst)
+      s.push_back('C');
+    if (pntr)
+      s.push_back('*');
+    return s.str();
+  }
+
+  // Since the return value must be one type, return a vector type of the
+  // appropriate width which we will bitcast.  An exception is made for
+  // returning structs of 2, 3, or 4 vectors which are returned in a sret-like
+  // fashion, storing them to a pointer arg.
+  if (ret) {
+    if (mod == '2' || mod == '3' || mod == '4')
+      return "vv*";
+    if (mod == 'f' || (ck != ClassB && type == 'f'))
+      return quad ? "V4f" : "V2f";
+    if (ck != ClassB && type == 's')
+      return quad ? "V8s" : "V4s";
+    if (ck != ClassB && type == 'i')
+      return quad ? "V4i" : "V2i";
+    if (ck != ClassB && type == 'l')
+      return quad ? "V2LLi" : "V1LLi";
+    
+    return quad ? "V16c" : "V8c";
+  }    
+
+  // Non-return array types are passed as individual vectors.
+  if (mod == '2')
+    return quad ? "V16cV16c" : "V8cV8c";
+  if (mod == '3')
+    return quad ? "V16cV16cV16c" : "V8cV8cV8c";
+  if (mod == '4')
+    return quad ? "V16cV16cV16cV16c" : "V8cV8cV8cV8c";
+
+  if (mod == 'f' || (ck != ClassB && type == 'f'))
+    return quad ? "V4f" : "V2f";
+  if (ck != ClassB && type == 's')
+    return quad ? "V8s" : "V4s";
+  if (ck != ClassB && type == 'i')
+    return quad ? "V4i" : "V2i";
+  if (ck != ClassB && type == 'l')
+    return quad ? "V2LLi" : "V1LLi";
+  
+  return quad ? "V16c" : "V8c";
+}
+
+/// StructTag - generate the name of the struct tag for a type.
+/// These names are mandated by ARM's ABI.
+static std::string StructTag(StringRef typestr) {
+  bool quad = false;
+  bool poly = false;
+  bool usgn = false;
+  
+  // base type to get the type string for.
+  char type = ClassifyType(typestr, quad, poly, usgn);
+  
+  SmallString<128> s;
+  s += "__simd";
+  s += quad ? "128_" : "64_";
+  if (usgn)
+    s.push_back('u');
+  
+  switch (type) {
+    case 'c':
+      s += poly ? "poly8" : "int8";
+      break;
+    case 's':
+      s += poly ? "poly16" : "int16";
+      break;
+    case 'i':
+      s += "int32";
+      break;
+    case 'l':
+      s += "int64";
+      break;
+    case 'h':
+      s += "float16";
+      break;
+    case 'f':
+      s += "float32";
+      break;
+    default:
+      throw "unhandled type!";
+      break;
+  }
+
+  // Append _t, finishing the struct tag name.
+  s += "_t";
+  
+  return s.str();
+}
+
+/// MangleName - Append a type or width suffix to a base neon function name, 
+/// and insert a 'q' in the appropriate location if the operation works on
+/// 128b rather than 64b.   E.g. turn "vst2_lane" into "vst2q_lane_f32", etc.
+static std::string MangleName(const std::string &name, StringRef typestr,
+                              ClassKind ck) {
+  if (name == "vcvt_f32_f16")
+    return name;
+  
+  bool quad = false;
+  bool poly = false;
+  bool usgn = false;
+  char type = ClassifyType(typestr, quad, poly, usgn);
+
+  std::string s = name;
+  
+  switch (type) {
+  case 'c':
+    switch (ck) {
+    case ClassS: s += poly ? "_p8" : usgn ? "_u8" : "_s8"; break;
+    case ClassI: s += "_i8"; break;
+    case ClassW: s += "_8"; break;
+    default: break;
+    }
+    break;
+  case 's':
+    switch (ck) {
+    case ClassS: s += poly ? "_p16" : usgn ? "_u16" : "_s16"; break;
+    case ClassI: s += "_i16"; break;
+    case ClassW: s += "_16"; break;
+    default: break;
+    }
+    break;
+  case 'i':
+    switch (ck) {
+    case ClassS: s += usgn ? "_u32" : "_s32"; break;
+    case ClassI: s += "_i32"; break;
+    case ClassW: s += "_32"; break;
+    default: break;
+    }
+    break;
+  case 'l':
+    switch (ck) {
+    case ClassS: s += usgn ? "_u64" : "_s64"; break;
+    case ClassI: s += "_i64"; break;
+    case ClassW: s += "_64"; break;
+    default: break;
+    }
+    break;
+  case 'h':
+    switch (ck) {
+    case ClassS:
+    case ClassI: s += "_f16"; break;
+    case ClassW: s += "_16"; break;
+    default: break;
+    }
+    break;
+  case 'f':
+    switch (ck) {
+    case ClassS:
+    case ClassI: s += "_f32"; break;
+    case ClassW: s += "_32"; break;
+    default: break;
+    }
+    break;
+  default:
+    throw "unhandled type!";
+    break;
+  }
+  if (ck == ClassB)
+    s += "_v";
+    
+  // Insert a 'q' before the first '_' character so that it ends up before 
+  // _lane or _n on vector-scalar operations.
+  if (quad) {
+    size_t pos = s.find('_');
+    s = s.insert(pos, "q");
+  }
+  return s;
+}
+
+// Generate the string "(argtype a, argtype b, ...)"
+static std::string GenArgs(const std::string &proto, StringRef typestr) {
+  bool define = proto.find('i') != std::string::npos;
+  char arg = 'a';
+  
+  std::string s;
+  s += "(";
+  
+  for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
+    if (!define) {
+      s += TypeString(proto[i], typestr);
+      s.push_back(' ');
+    }
+    s.push_back(arg);
+    if ((i + 1) < e)
+      s += ", ";
+  }
+  
+  s += ")";
+  return s;
+}
+
+static std::string Duplicate(unsigned nElts, StringRef typestr, 
+                             const std::string &a) {
+  std::string s;
+  
+  s = "(__neon_" + TypeString('d', typestr) + "){ ";
+  for (unsigned i = 0; i != nElts; ++i) {
+    s += a;
+    if ((i + 1) < nElts)
+      s += ", ";
+  }
+  s += " }";
+  
+  return s;
+}
+
+// Generate the definition for this intrinsic, e.g. "a + b" for OpAdd.
+// If structTypes is true, the NEON types are structs of vector types rather
+// than vector types, and the call becomes "a.val + b.val"
+static std::string GenOpString(OpKind op, const std::string &proto,
+                               StringRef typestr, bool structTypes = true) {
+  bool dummy, quad = false;
+  char type = ClassifyType(typestr, quad, dummy, dummy);
+  unsigned nElts = 0;
+  switch (type) {
+    case 'c': nElts = 8; break;
+    case 's': nElts = 4; break;
+    case 'i': nElts = 2; break;
+    case 'l': nElts = 1; break;
+    case 'h': nElts = 4; break;
+    case 'f': nElts = 2; break;
+  }
+  
+  std::string ts = TypeString(proto[0], typestr);
+  std::string s = ts + " r; r";
+  
+  if (structTypes)
+    s += ".val";
+  
+  s += " = ";
+
+  std::string a, b, c;
+  if (proto.size() > 1)
+    a = (structTypes && proto[1] != 'l' && proto[1] != 's') ? "a.val" : "a";
+  b = structTypes ? "b.val" : "b";
+  c = structTypes ? "c.val" : "c";
+  
+  switch(op) {
+  case OpAdd:
+    s += a + " + " + b;
+    break;
+  case OpSub:
+    s += a + " - " + b;
+    break;
+  case OpMulN:
+    b = Duplicate(nElts << (int)quad, typestr, "b");
+  case OpMul:
+    s += a + " * " + b;
+    break;
+  case OpMlaN:
+    c = Duplicate(nElts << (int)quad, typestr, "c");
+  case OpMla:
+    s += a + " + ( " + b + " * " + c + " )";
+    break;
+  case OpMlsN:
+    c = Duplicate(nElts << (int)quad, typestr, "c");
+  case OpMls:
+    s += a + " - ( " + b + " * " + c + " )";
+    break;
+  case OpEq:
+    s += "(__neon_" + ts + ")(" + a + " == " + b + ")";
+    break;
+  case OpGe:
+    s += "(__neon_" + ts + ")(" + a + " >= " + b + ")";
+    break;
+  case OpLe:
+    s += "(__neon_" + ts + ")(" + a + " <= " + b + ")";
+    break;
+  case OpGt:
+    s += "(__neon_" + ts + ")(" + a + " > " + b + ")";
+    break;
+  case OpLt:
+    s += "(__neon_" + ts + ")(" + a + " < " + b + ")";
+    break;
+  case OpNeg:
+    s += " -" + a;
+    break;
+  case OpNot:
+    s += " ~" + a;
+    break;
+  case OpAnd:
+    s += a + " & " + b;
+    break;
+  case OpOr:
+    s += a + " | " + b;
+    break;
+  case OpXor:
+    s += a + " ^ " + b;
+    break;
+  case OpAndNot:
+    s += a + " & ~" + b;
+    break;
+  case OpOrNot:
+    s += a + " | ~" + b;
+    break;
+  case OpCast:
+    s += "(__neon_" + ts + ")" + a;
+    break;
+  case OpConcat:
+    s += "__builtin_shufflevector((__neon_int64x1_t)" + a;
+    s += ", (__neon_int64x1_t)" + b + ", 0, 1)";
+    break;
+  case OpHi:
+    s += "(__neon_int64x1_t)(((__neon_int64x2_t)" + a + ")[1])";
+    break;
+  case OpLo:
+    s += "(__neon_int64x1_t)(((__neon_int64x2_t)" + a + ")[0])";
+    break;
+  case OpDup:
+    s += Duplicate(nElts << (int)quad, typestr, a);
+    break;
+  case OpSelect:
+    // ((0 & 1) | (~0 & 2))
+    ts = TypeString(proto[1], typestr);
+    s += "( " + a + " & (__neon_" + ts + ")" + b + ") | ";
+    s += "(~" + a + " & (__neon_" + ts + ")" + c + ")";
+    break;
+  case OpRev16:
+    s += "__builtin_shufflevector(" + a + ", " + a;
+    for (unsigned i = 2; i <= nElts << (int)quad; i += 2)
+      for (unsigned j = 0; j != 2; ++j)
+        s += ", " + utostr(i - j - 1);
+    s += ")";
+    break;
+  case OpRev32:
+    nElts >>= 1;
+    s += "__builtin_shufflevector(" + a + ", " + a;
+    for (unsigned i = nElts; i <= nElts << (1 + (int)quad); i += nElts)
+      for (unsigned j = 0; j != nElts; ++j)
+        s += ", " + utostr(i - j - 1);
+    s += ")";
+    break;
+  case OpRev64:
+    s += "__builtin_shufflevector(" + a + ", " + a;
+    for (unsigned i = nElts; i <= nElts << (int)quad; i += nElts)
+      for (unsigned j = 0; j != nElts; ++j)
+        s += ", " + utostr(i - j - 1);
+    s += ")";
+    break;
+  default:
+    throw "unknown OpKind!";
+    break;
+  }
+  s += "; return r;";
+  return s;
+}
+
+static unsigned GetNeonEnum(const std::string &proto, StringRef typestr) {
+  unsigned mod = proto[0];
+  unsigned ret = 0;
+
+  if (mod == 'v' || mod == 'f')
+    mod = proto[1];
+
+  bool quad = false;
+  bool poly = false;
+  bool usgn = false;
+  bool scal = false;
+  bool cnst = false;
+  bool pntr = false;
+  
+  // Base type to get the type string for.
+  char type = ClassifyType(typestr, quad, poly, usgn);
+  
+  // Based on the modifying character, change the type and width if necessary.
+  type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr);
+
+  if (usgn)
+    ret |= 0x08;
+  if (quad && proto[1] != 'g')
+    ret |= 0x10;
+  
+  switch (type) {
+    case 'c': 
+      ret |= poly ? 5 : 0;
+      break;
+    case 's':
+      ret |= poly ? 6 : 1;
+      break;
+    case 'i':
+      ret |= 2;
+      break;
+    case 'l':
+      ret |= 3;
+      break;
+    case 'h':
+      ret |= 7;
+      break;
+    case 'f':
+      ret |= 4;
+      break;
+    default:
+      throw "unhandled type!";
+      break;
+  }
+  return ret;
+}
+
+// Generate the definition for this intrinsic, e.g. __builtin_neon_cls(a)
+// If structTypes is true, the NEON types are structs of vector types rather
+// than vector types, and the call becomes __builtin_neon_cls(a.val)
+static std::string GenBuiltin(const std::string &name, const std::string &proto,
+                              StringRef typestr, ClassKind ck,
+                              bool structTypes = true) {
+  bool dummy, quad = false;
+  char type = ClassifyType(typestr, quad, dummy, dummy);
+  unsigned nElts = 0;
+  switch (type) {
+    case 'c': nElts = 8; break;
+    case 's': nElts = 4; break;
+    case 'i': nElts = 2; break;
+    case 'l': nElts = 1; break;
+    case 'h': nElts = 4; break;
+    case 'f': nElts = 2; break;
+  }
+  if (quad) nElts <<= 1;
+
+  char arg = 'a';
+  std::string s;
+
+  // If this builtin returns a struct 2, 3, or 4 vectors, pass it as an implicit
+  // sret-like argument.
+  bool sret = (proto[0] == '2' || proto[0] == '3' || proto[0] == '4');
+
+  // If this builtin takes an immediate argument, we need to #define it rather
+  // than use a standard declaration, so that SemaChecking can range check
+  // the immediate passed by the user.
+  bool define = proto.find('i') != std::string::npos;
+
+  // If all types are the same size, bitcasting the args will take care 
+  // of arg checking.  The actual signedness etc. will be taken care of with
+  // special enums.
+  if (proto.find('s') == std::string::npos)
+    ck = ClassB;
+
+  if (proto[0] != 'v') {
+    std::string ts = TypeString(proto[0], typestr);
+    
+    if (define) {
+      if (sret)
+        s += "({ " + ts + " r; ";
+      else if (proto[0] != 's')
+        s += "(" + ts + "){(__neon_" + ts + ")";
+    } else if (sret) {
+      s += ts + " r; ";
+    } else {
+      s += ts + " r; r";
+      if (structTypes && proto[0] != 's' && proto[0] != 'i' && proto[0] != 'l')
+        s += ".val";
+      
+      s += " = ";
+    }
+  }
+  
+  bool splat = proto.find('a') != std::string::npos;
+  
+  s += "__builtin_neon_";
+  if (splat) {
+    std::string vname(name, 0, name.size()-2);
+    s += MangleName(vname, typestr, ck);
+  } else {
+    s += MangleName(name, typestr, ck);
+  }
+  s += "(";
+
+  // Pass the address of the return variable as the first argument to sret-like
+  // builtins.
+  if (sret)
+    s += "&r, ";
+  
+  for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
+    std::string args = std::string(&arg, 1);
+    if (define)
+      args = "(" + args + ")";
+    
+    // Handle multiple-vector values specially, emitting each subvector as an
+    // argument to the __builtin.
+    if (structTypes && (proto[i] == '2' || proto[i] == '3' || proto[i] == '4')){
+      for (unsigned vi = 0, ve = proto[i] - '0'; vi != ve; ++vi) {
+        s += args + ".val[" + utostr(vi) + "].val";
+        if ((vi + 1) < ve)
+          s += ", ";
+      }
+      if ((i + 1) < e)
+        s += ", ";
+
+      continue;
+    }
+    
+    if (splat && (i + 1) == e) 
+      s += Duplicate(nElts, typestr, args);
+    else
+      s += args;
+    
+    if (structTypes && proto[i] != 's' && proto[i] != 'i' && proto[i] != 'l' &&
+        proto[i] != 'p' && proto[i] != 'c' && proto[i] != 'a') {
+      s += ".val";
+    }
+    if ((i + 1) < e)
+      s += ", ";
+  }
+  
+  // Extra constant integer to hold type class enum for this function, e.g. s8
+  if (ck == ClassB)
+    s += ", " + utostr(GetNeonEnum(proto, typestr));
+  
+  if (define)
+    s += ")";
+  else
+    s += ");";
+
+  if (proto[0] != 'v') {
+    if (define) {
+      if (sret)
+        s += "; r; })";
+      else if (proto[0] != 's')
+        s += "}";
+    } else {
+      s += " return r;";
+    }
+  }
+  return s;
+}
+
+static std::string GenBuiltinDef(const std::string &name, 
+                                 const std::string &proto,
+                                 StringRef typestr, ClassKind ck) {
+  std::string s("BUILTIN(__builtin_neon_");
+
+  // If all types are the same size, bitcasting the args will take care 
+  // of arg checking.  The actual signedness etc. will be taken care of with
+  // special enums.
+  if (proto.find('s') == std::string::npos)
+    ck = ClassB;
+  
+  s += MangleName(name, typestr, ck);
+  s += ", \"";
+  
+  for (unsigned i = 0, e = proto.size(); i != e; ++i)
+    s += BuiltinTypeString(proto[i], typestr, ck, i == 0);
+
+  // Extra constant integer to hold type class enum for this function, e.g. s8
+  if (ck == ClassB)
+    s += "i";
+  
+  s += "\", \"n\")";
+  return s;
+}
+
+/// run - Read the records in arm_neon.td and output arm_neon.h.  arm_neon.h
+/// is comprised of type definitions and function declarations.
+void NeonEmitter::run(raw_ostream &OS) {
+  EmitSourceFileHeader("ARM NEON Header", OS);
+  
+  // FIXME: emit license into file?
+  
+  OS << "#ifndef __ARM_NEON_H\n";
+  OS << "#define __ARM_NEON_H\n\n";
+  
+  OS << "#ifndef __ARM_NEON__\n";
+  OS << "#error \"NEON support not enabled\"\n";
+  OS << "#endif\n\n";
+
+  OS << "#include <stdint.h>\n\n";
+
+  // Emit NEON-specific scalar typedefs.
+  OS << "typedef float float32_t;\n";
+  OS << "typedef uint8_t poly8_t;\n";
+  OS << "typedef uint16_t poly16_t;\n";
+  OS << "typedef uint16_t float16_t;\n";
+
+  // Emit Neon vector typedefs.
+  std::string TypedefTypes("cQcsQsiQilQlUcQUcUsQUsUiQUiUlQUlhQhfQfPcQPcPsQPs");
+  SmallVector<StringRef, 24> TDTypeVec;
+  ParseTypes(0, TypedefTypes, TDTypeVec);
+
+  // Emit vector typedefs.
+  for (unsigned v = 1; v != 5; ++v) {
+    for (unsigned i = 0, e = TDTypeVec.size(); i != e; ++i) {
+      bool dummy, quad = false;
+      (void) ClassifyType(TDTypeVec[i], quad, dummy, dummy);
+      OS << "typedef __attribute__(( __vector_size__(";
+      
+      OS << utostr(8*v*(quad ? 2 : 1)) << ") )) ";
+      if (!quad)
+        OS << " ";
+      
+      OS << TypeString('s', TDTypeVec[i]);
+      OS << " __neon_";
+      
+      char t = (v == 1) ? 'd' : '0' + v;
+      OS << TypeString(t, TDTypeVec[i]) << ";\n";
+    }
+  }
+  OS << "\n";
+
+  // Emit struct typedefs.
+  for (unsigned vi = 1; vi != 5; ++vi) {
+    for (unsigned i = 0, e = TDTypeVec.size(); i != e; ++i) {
+      std::string ts = TypeString('d', TDTypeVec[i], vi == 1);
+      std::string vs = TypeString((vi > 1) ? '0' + vi : 'd', TDTypeVec[i]);
+      std::string tag = (vi > 1) ? vs : StructTag(TDTypeVec[i]);
+      OS << "typedef struct " << tag << " {\n";
+      OS << "  " << ts << " val";
+      if (vi > 1)
+        OS << "[" << utostr(vi) << "]";
+      OS << ";\n} " << vs << ";\n\n";
+    }
+  }
+  
+  OS << "#define __ai static __attribute__((__always_inline__))\n\n";
+
+  std::vector<Record*> RV = Records.getAllDerivedDefinitions("Inst");
+  
+  // Unique the return+pattern types, and assign them.
+  for (unsigned i = 0, e = RV.size(); i != e; ++i) {
+    Record *R = RV[i];
+    std::string name = LowercaseString(R->getName());
+    std::string Proto = R->getValueAsString("Prototype");
+    std::string Types = R->getValueAsString("Types");
+    
+    SmallVector<StringRef, 16> TypeVec;
+    ParseTypes(R, Types, TypeVec);
+    
+    OpKind k = OpMap[R->getValueAsDef("Operand")->getName()];
+    
+    bool define = Proto.find('i') != std::string::npos;
+    
+    for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
+      assert(!Proto.empty() && "");
+      
+      // static always inline + return type
+      if (define)
+        OS << "#define";
+      else
+        OS << "__ai " << TypeString(Proto[0], TypeVec[ti]);
+      
+      // Function name with type suffix
+      OS << " " << MangleName(name, TypeVec[ti], ClassS);
+      
+      // Function arguments
+      OS << GenArgs(Proto, TypeVec[ti]);
+      
+      // Definition.
+      if (define)
+        OS << " ";
+      else
+        OS << " { ";
+      
+      if (k != OpNone) {
+        OS << GenOpString(k, Proto, TypeVec[ti]);
+      } else {
+        if (R->getSuperClasses().size() < 2)
+          throw TGError(R->getLoc(), "Builtin has no class kind");
+        
+        ClassKind ck = ClassMap[R->getSuperClasses()[1]];
+
+        if (ck == ClassNone)
+          throw TGError(R->getLoc(), "Builtin has no class kind");
+        OS << GenBuiltin(name, Proto, TypeVec[ti], ck);
+      }
+      if (!define)
+        OS << " }";
+      OS << "\n";
+    }
+    OS << "\n";
+  }
+  OS << "#undef __ai\n\n";
+  OS << "#endif /* __ARM_NEON_H */\n";
+}
+
+static unsigned RangeFromType(StringRef typestr) {
+  // base type to get the type string for.
+  bool quad = false, dummy = false;
+  char type = ClassifyType(typestr, quad, dummy, dummy);
+  
+  switch (type) {
+    case 'c':
+      return (8 << (int)quad) - 1;
+    case 'h':
+    case 's':
+      return (4 << (int)quad) - 1;
+    case 'f':
+    case 'i':
+      return (2 << (int)quad) - 1;
+    case 'l':
+      return (1 << (int)quad) - 1;
+    default:
+      throw "unhandled type!";
+      break;
+  }
+  assert(0 && "unreachable");
+  return 0;
+}
+
+/// runHeader - Emit a file with sections defining:
+/// 1. the NEON section of BuiltinsARM.def.
+/// 2. the SemaChecking code for the type overload checking.
+/// 3. the SemaChecking code for validation of intrinsic immedate arguments.
+void NeonEmitter::runHeader(raw_ostream &OS) {
+  std::vector<Record*> RV = Records.getAllDerivedDefinitions("Inst");
+
+  StringMap<OpKind> EmittedMap;
+  
+  // Generate BuiltinsARM.def for NEON
+  OS << "#ifdef GET_NEON_BUILTINS\n";
+  for (unsigned i = 0, e = RV.size(); i != e; ++i) {
+    Record *R = RV[i];
+    OpKind k = OpMap[R->getValueAsDef("Operand")->getName()];
+    if (k != OpNone)
+      continue;
+
+    std::string Proto = R->getValueAsString("Prototype");
+    
+    // Functions with 'a' (the splat code) in the type prototype should not get
+    // their own builtin as they use the non-splat variant.
+    if (Proto.find('a') != std::string::npos)
+      continue;
+    
+    std::string Types = R->getValueAsString("Types");
+    SmallVector<StringRef, 16> TypeVec;
+    ParseTypes(R, Types, TypeVec);
+    
+    if (R->getSuperClasses().size() < 2)
+      throw TGError(R->getLoc(), "Builtin has no class kind");
+    
+    std::string name = LowercaseString(R->getName());
+    ClassKind ck = ClassMap[R->getSuperClasses()[1]];
+    
+    for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
+      // Generate the BuiltinsARM.def declaration for this builtin, ensuring
+      // that each unique BUILTIN() macro appears only once in the output
+      // stream.
+      std::string bd = GenBuiltinDef(name, Proto, TypeVec[ti], ck);
+      if (EmittedMap.count(bd))
+        continue;
+      
+      EmittedMap[bd] = OpNone;
+      OS << bd << "\n";
+    }
+  }
+  OS << "#endif\n\n";
+  
+  // Generate the overloaded type checking code for SemaChecking.cpp
+  OS << "#ifdef GET_NEON_OVERLOAD_CHECK\n";
+  for (unsigned i = 0, e = RV.size(); i != e; ++i) {
+    Record *R = RV[i];
+    OpKind k = OpMap[R->getValueAsDef("Operand")->getName()];
+    if (k != OpNone)
+      continue;
+    
+    std::string Proto = R->getValueAsString("Prototype");
+    std::string Types = R->getValueAsString("Types");
+    std::string name = LowercaseString(R->getName());
+    
+    // Functions with 'a' (the splat code) in the type prototype should not get
+    // their own builtin as they use the non-splat variant.
+    if (Proto.find('a') != std::string::npos)
+      continue;
+    
+    // Functions which have a scalar argument cannot be overloaded, no need to
+    // check them if we are emitting the type checking code.
+    if (Proto.find('s') != std::string::npos)
+      continue;
+    
+    SmallVector<StringRef, 16> TypeVec;
+    ParseTypes(R, Types, TypeVec);
+    
+    if (R->getSuperClasses().size() < 2)
+      throw TGError(R->getLoc(), "Builtin has no class kind");
+    
+    int si = -1, qi = -1;
+    unsigned mask = 0, qmask = 0;
+    for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
+      // Generate the switch case(s) for this builtin for the type validation.
+      bool quad = false, poly = false, usgn = false;
+      (void) ClassifyType(TypeVec[ti], quad, poly, usgn);
+      
+      if (quad) {
+        qi = ti;
+        qmask |= 1 << GetNeonEnum(Proto, TypeVec[ti]);
+      } else {
+        si = ti;
+        mask |= 1 << GetNeonEnum(Proto, TypeVec[ti]);
+      }
+    }
+    if (mask)
+      OS << "case ARM::BI__builtin_neon_" 
+      << MangleName(name, TypeVec[si], ClassB)
+      << ": mask = " << "0x" << utohexstr(mask) << "; break;\n";
+    if (qmask)
+      OS << "case ARM::BI__builtin_neon_" 
+      << MangleName(name, TypeVec[qi], ClassB)
+      << ": mask = " << "0x" << utohexstr(qmask) << "; break;\n";
+  }
+  OS << "#endif\n\n";
+  
+  // Generate the intrinsic range checking code for shift/lane immediates.
+  OS << "#ifdef GET_NEON_IMMEDIATE_CHECK\n";
+  for (unsigned i = 0, e = RV.size(); i != e; ++i) {
+    Record *R = RV[i];
+    
+    OpKind k = OpMap[R->getValueAsDef("Operand")->getName()];
+    if (k != OpNone)
+      continue;
+    
+    std::string name = LowercaseString(R->getName());
+    std::string Proto = R->getValueAsString("Prototype");
+    std::string Types = R->getValueAsString("Types");
+    
+    // Functions with 'a' (the splat code) in the type prototype should not get
+    // their own builtin as they use the non-splat variant.
+    if (Proto.find('a') != std::string::npos)
+      continue;
+    
+    // Functions which do not have an immediate do not need to have range
+    // checking code emitted.
+    if (Proto.find('i') == std::string::npos)
+      continue;
+    
+    SmallVector<StringRef, 16> TypeVec;
+    ParseTypes(R, Types, TypeVec);
+    
+    if (R->getSuperClasses().size() < 2)
+      throw TGError(R->getLoc(), "Builtin has no class kind");
+    
+    ClassKind ck = ClassMap[R->getSuperClasses()[1]];
+    
+    for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
+      std::string namestr, shiftstr, rangestr;
+      
+      // Builtins which are overloaded by type will need to have their upper
+      // bound computed at Sema time based on the type constant.
+      if (Proto.find('s') == std::string::npos) {
+        ck = ClassB;
+        if (R->getValueAsBit("isShift")) {
+          shiftstr = ", true";
+          
+          // Right shifts have an 'r' in the name, left shifts do not.
+          if (name.find('r') != std::string::npos)
+            rangestr = "l = 1; ";
+        }
+        rangestr += "u = RFT(TV" + shiftstr + ")";
+      } else {
+        rangestr = "u = " + utostr(RangeFromType(TypeVec[ti]));
+      }
+      // Make sure cases appear only once by uniquing them in a string map.
+      namestr = MangleName(name, TypeVec[ti], ck);
+      if (EmittedMap.count(namestr))
+        continue;
+      EmittedMap[namestr] = OpNone;
+
+      // Calculate the index of the immediate that should be range checked.
+      unsigned immidx = 0;
+      
+      // Builtins that return a struct of multiple vectors have an extra
+      // leading arg for the struct return.
+      if (Proto[0] == '2' || Proto[0] == '3' || Proto[0] == '4')
+        ++immidx;
+      
+      // Add one to the index for each argument until we reach the immediate 
+      // to be checked.  Structs of vectors are passed as multiple arguments.
+      for (unsigned ii = 1, ie = Proto.size(); ii != ie; ++ii) {
+        switch (Proto[ii]) {
+          default:  immidx += 1; break;
+          case '2': immidx += 2; break;
+          case '3': immidx += 3; break;
+          case '4': immidx += 4; break;
+          case 'i': ie = ii + 1; break;
+        }
+      }
+      OS << "case ARM::BI__builtin_neon_"  << MangleName(name, TypeVec[ti], ck)
+         << ": i = " << immidx << "; " << rangestr << "; break;\n";
+    }
+  }
+  OS << "#endif\n\n";
+}
diff --git a/src/LLVM/utils/TableGen/NeonEmitter.h b/src/LLVM/utils/TableGen/NeonEmitter.h
new file mode 100644
index 0000000..6c6760d
--- /dev/null
+++ b/src/LLVM/utils/TableGen/NeonEmitter.h
@@ -0,0 +1,122 @@
+//===- NeonEmitter.h - Generate arm_neon.h for use with clang ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend is responsible for emitting arm_neon.h, which includes
+// a declaration and definition of each function specified by the ARM NEON 
+// compiler interface.  See ARM document DUI0348B.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef NEON_EMITTER_H
+#define NEON_EMITTER_H
+
+#include "Record.h"
+#include "TableGenBackend.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringMap.h"
+
+enum OpKind {
+  OpNone,
+  OpAdd,
+  OpSub,
+  OpMul,
+  OpMla,
+  OpMls,
+  OpMulN,
+  OpMlaN,
+  OpMlsN,
+  OpEq,
+  OpGe,
+  OpLe,
+  OpGt,
+  OpLt,
+  OpNeg,
+  OpNot,
+  OpAnd,
+  OpOr,
+  OpXor,
+  OpAndNot,
+  OpOrNot,
+  OpCast,
+  OpConcat,
+  OpDup,
+  OpHi,
+  OpLo,
+  OpSelect,
+  OpRev16,
+  OpRev32,
+  OpRev64
+};
+
+enum ClassKind {
+  ClassNone,
+  ClassI,
+  ClassS,
+  ClassW,
+  ClassB
+};
+
+namespace llvm {
+  
+  class NeonEmitter : public TableGenBackend {
+    RecordKeeper &Records;
+    StringMap<OpKind> OpMap;
+    DenseMap<Record*, ClassKind> ClassMap;
+    
+  public:
+    NeonEmitter(RecordKeeper &R) : Records(R) {
+      OpMap["OP_NONE"]  = OpNone;
+      OpMap["OP_ADD"]   = OpAdd;
+      OpMap["OP_SUB"]   = OpSub;
+      OpMap["OP_MUL"]   = OpMul;
+      OpMap["OP_MLA"]   = OpMla;
+      OpMap["OP_MLS"]   = OpMls;
+      OpMap["OP_MUL_N"] = OpMulN;
+      OpMap["OP_MLA_N"] = OpMlaN;
+      OpMap["OP_MLS_N"] = OpMlsN;
+      OpMap["OP_EQ"]    = OpEq;
+      OpMap["OP_GE"]    = OpGe;
+      OpMap["OP_LE"]    = OpLe;
+      OpMap["OP_GT"]    = OpGt;
+      OpMap["OP_LT"]    = OpLt;
+      OpMap["OP_NEG"]   = OpNeg;
+      OpMap["OP_NOT"]   = OpNot;
+      OpMap["OP_AND"]   = OpAnd;
+      OpMap["OP_OR"]    = OpOr;
+      OpMap["OP_XOR"]   = OpXor;
+      OpMap["OP_ANDN"]  = OpAndNot;
+      OpMap["OP_ORN"]   = OpOrNot;
+      OpMap["OP_CAST"]  = OpCast;
+      OpMap["OP_CONC"]  = OpConcat;
+      OpMap["OP_HI"]    = OpHi;
+      OpMap["OP_LO"]    = OpLo;
+      OpMap["OP_DUP"]   = OpDup;
+      OpMap["OP_SEL"]   = OpSelect;
+      OpMap["OP_REV16"] = OpRev16;
+      OpMap["OP_REV32"] = OpRev32;
+      OpMap["OP_REV64"] = OpRev64;
+
+      Record *SI = R.getClass("SInst");
+      Record *II = R.getClass("IInst");
+      Record *WI = R.getClass("WInst");
+      ClassMap[SI] = ClassS;
+      ClassMap[II] = ClassI;
+      ClassMap[WI] = ClassW;
+    }
+    
+    // run - Emit arm_neon.h.inc
+    void run(raw_ostream &o);
+
+    // runHeader - Emit all the __builtin prototypes used in arm_neon.h
+    void runHeader(raw_ostream &o);
+  };
+  
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/utils/TableGen/OptParserEmitter.cpp b/src/LLVM/utils/TableGen/OptParserEmitter.cpp
new file mode 100644
index 0000000..6892912
--- /dev/null
+++ b/src/LLVM/utils/TableGen/OptParserEmitter.cpp
@@ -0,0 +1,194 @@
+//===- OptParserEmitter.cpp - Table Driven Command Line Parsing -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "OptParserEmitter.h"
+#include "Record.h"
+#include "llvm/ADT/STLExtras.h"
+using namespace llvm;
+
+static int StrCmpOptionName(const char *A, const char *B) {
+  char a = *A, b = *B;
+  while (a == b) {
+    if (a == '\0')
+      return 0;
+
+    a = *++A;
+    b = *++B;
+  }
+
+  if (a == '\0') // A is a prefix of B.
+    return 1;
+  if (b == '\0') // B is a prefix of A.
+    return -1;
+
+  // Otherwise lexicographic.
+  return (a < b) ? -1 : 1;
+}
+
+static int CompareOptionRecords(const void *Av, const void *Bv) {
+  const Record *A = *(Record**) Av;
+  const Record *B = *(Record**) Bv;
+
+  // Sentinel options preceed all others and are only ordered by precedence.
+  bool ASent = A->getValueAsDef("Kind")->getValueAsBit("Sentinel");
+  bool BSent = B->getValueAsDef("Kind")->getValueAsBit("Sentinel");
+  if (ASent != BSent)
+    return ASent ? -1 : 1;
+
+  // Compare options by name, unless they are sentinels.
+  if (!ASent)
+    if (int Cmp = StrCmpOptionName(A->getValueAsString("Name").c_str(),
+                                   B->getValueAsString("Name").c_str()))
+    return Cmp;
+
+  // Then by the kind precedence;
+  int APrec = A->getValueAsDef("Kind")->getValueAsInt("Precedence");
+  int BPrec = B->getValueAsDef("Kind")->getValueAsInt("Precedence");
+  assert(APrec != BPrec && "Options are equivalent!");
+  return APrec < BPrec ? -1 : 1;
+}
+
+static const std::string getOptionName(const Record &R) {
+  // Use the record name unless EnumName is defined.
+  if (dynamic_cast<UnsetInit*>(R.getValueInit("EnumName")))
+    return R.getName();
+
+  return R.getValueAsString("EnumName");
+}
+
+static raw_ostream &write_cstring(raw_ostream &OS, llvm::StringRef Str) {
+  OS << '"';
+  OS.write_escaped(Str);
+  OS << '"';
+  return OS;
+}
+
+void OptParserEmitter::run(raw_ostream &OS) {
+  // Get the option groups and options.
+  const std::vector<Record*> &Groups =
+    Records.getAllDerivedDefinitions("OptionGroup");
+  std::vector<Record*> Opts = Records.getAllDerivedDefinitions("Option");
+
+  if (GenDefs)
+    EmitSourceFileHeader("Option Parsing Definitions", OS);
+  else
+    EmitSourceFileHeader("Option Parsing Table", OS);
+
+  array_pod_sort(Opts.begin(), Opts.end(), CompareOptionRecords);
+  if (GenDefs) {
+    OS << "#ifndef OPTION\n";
+    OS << "#error \"Define OPTION prior to including this file!\"\n";
+    OS << "#endif\n\n";
+
+    OS << "/////////\n";
+    OS << "// Groups\n\n";
+    for (unsigned i = 0, e = Groups.size(); i != e; ++i) {
+      const Record &R = *Groups[i];
+
+      // Start a single option entry.
+      OS << "OPTION(";
+
+      // The option string.
+      OS << '"' << R.getValueAsString("Name") << '"';
+
+      // The option identifier name.
+      OS  << ", "<< getOptionName(R);
+
+      // The option kind.
+      OS << ", Group";
+
+      // The containing option group (if any).
+      OS << ", ";
+      if (const DefInit *DI = dynamic_cast<DefInit*>(R.getValueInit("Group")))
+        OS << getOptionName(*DI->getDef());
+      else
+        OS << "INVALID";
+
+      // The other option arguments (unused for groups).
+      OS << ", INVALID, 0, 0";
+
+      // The option help text.
+      if (!dynamic_cast<UnsetInit*>(R.getValueInit("HelpText"))) {
+        OS << ",\n";
+        OS << "       ";
+        write_cstring(OS, R.getValueAsString("HelpText"));
+      } else
+        OS << ", 0";
+
+      // The option meta-variable name (unused).
+      OS << ", 0)\n";
+    }
+    OS << "\n";
+
+    OS << "//////////\n";
+    OS << "// Options\n\n";
+    for (unsigned i = 0, e = Opts.size(); i != e; ++i) {
+      const Record &R = *Opts[i];
+
+      // Start a single option entry.
+      OS << "OPTION(";
+
+      // The option string.
+      write_cstring(OS, R.getValueAsString("Name"));
+
+      // The option identifier name.
+      OS  << ", "<< getOptionName(R);
+
+      // The option kind.
+      OS << ", " << R.getValueAsDef("Kind")->getValueAsString("Name");
+
+      // The containing option group (if any).
+      OS << ", ";
+      if (const DefInit *DI = dynamic_cast<DefInit*>(R.getValueInit("Group")))
+        OS << getOptionName(*DI->getDef());
+      else
+        OS << "INVALID";
+
+      // The option alias (if any).
+      OS << ", ";
+      if (const DefInit *DI = dynamic_cast<DefInit*>(R.getValueInit("Alias")))
+        OS << getOptionName(*DI->getDef());
+      else
+        OS << "INVALID";
+
+      // The option flags.
+      const ListInit *LI = R.getValueAsListInit("Flags");
+      if (LI->empty()) {
+        OS << ", 0";
+      } else {
+        OS << ", ";
+        for (unsigned i = 0, e = LI->size(); i != e; ++i) {
+          if (i)
+            OS << " | ";
+          OS << dynamic_cast<DefInit*>(LI->getElement(i))->getDef()->getName();
+        }
+      }
+
+      // The option parameter field.
+      OS << ", " << R.getValueAsInt("NumArgs");
+
+      // The option help text.
+      if (!dynamic_cast<UnsetInit*>(R.getValueInit("HelpText"))) {
+        OS << ",\n";
+        OS << "       ";
+        write_cstring(OS, R.getValueAsString("HelpText"));
+      } else
+        OS << ", 0";
+
+      // The option meta-variable name.
+      OS << ", ";
+      if (!dynamic_cast<UnsetInit*>(R.getValueInit("MetaVarName")))
+        write_cstring(OS, R.getValueAsString("MetaVarName"));
+      else
+        OS << "0";
+
+      OS << ")\n";
+    }
+  }
+}
diff --git a/src/LLVM/utils/TableGen/OptParserEmitter.h b/src/LLVM/utils/TableGen/OptParserEmitter.h
new file mode 100644
index 0000000..241a3f2
--- /dev/null
+++ b/src/LLVM/utils/TableGen/OptParserEmitter.h
@@ -0,0 +1,34 @@
+//===- OptParserEmitter.h - Table Driven Command Line Parsing ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef UTILS_TABLEGEN_OPTPARSEREMITTER_H
+#define UTILS_TABLEGEN_OPTPARSEREMITTER_H
+
+#include "TableGenBackend.h"
+
+namespace llvm {
+  /// OptParserEmitter - This tablegen backend takes an input .td file
+  /// describing a list of options and emits a data structure for parsing and
+  /// working with those options when given an input command line.
+  class OptParserEmitter : public TableGenBackend {
+    RecordKeeper &Records;
+    bool GenDefs;
+
+  public:
+    OptParserEmitter(RecordKeeper &R, bool _GenDefs)
+      : Records(R), GenDefs(_GenDefs) {}
+
+    /// run - Output the option parsing information.
+    ///
+    /// \param GenHeader - Generate the header describing the option IDs.x
+    void run(raw_ostream &OS);
+  };
+}
+
+#endif
diff --git a/src/LLVM/utils/TableGen/Record.cpp b/src/LLVM/utils/TableGen/Record.cpp
new file mode 100644
index 0000000..d2cf379
--- /dev/null
+++ b/src/LLVM/utils/TableGen/Record.cpp
@@ -0,0 +1,1594 @@
+//===- Record.cpp - Record implementation ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implement the tablegen record classes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Record.h"
+#include "llvm/System/DataTypes.h"
+#include "llvm/Support/Format.h"
+#include "llvm/ADT/StringExtras.h"
+
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+//    Type implementations
+//===----------------------------------------------------------------------===//
+
+void RecTy::dump() const { print(errs()); }
+
+Init *BitRecTy::convertValue(BitsInit *BI) {
+  if (BI->getNumBits() != 1) return 0; // Only accept if just one bit!
+  return BI->getBit(0);
+}
+
+bool BitRecTy::baseClassOf(const BitsRecTy *RHS) const {
+  return RHS->getNumBits() == 1;
+}
+
+Init *BitRecTy::convertValue(IntInit *II) {
+  int64_t Val = II->getValue();
+  if (Val != 0 && Val != 1) return 0;  // Only accept 0 or 1 for a bit!
+
+  return new BitInit(Val != 0);
+}
+
+Init *BitRecTy::convertValue(TypedInit *VI) {
+  if (dynamic_cast<BitRecTy*>(VI->getType()))
+    return VI;  // Accept variable if it is already of bit type!
+  return 0;
+}
+
+std::string BitsRecTy::getAsString() const {
+  return "bits<" + utostr(Size) + ">";
+}
+
+Init *BitsRecTy::convertValue(UnsetInit *UI) {
+  BitsInit *Ret = new BitsInit(Size);
+
+  for (unsigned i = 0; i != Size; ++i)
+    Ret->setBit(i, new UnsetInit());
+  return Ret;
+}
+
+Init *BitsRecTy::convertValue(BitInit *UI) {
+  if (Size != 1) return 0;  // Can only convert single bit...
+  BitsInit *Ret = new BitsInit(1);
+  Ret->setBit(0, UI);
+  return Ret;
+}
+
+// convertValue from Int initializer to bits type: Split the integer up into the
+// appropriate bits...
+//
+Init *BitsRecTy::convertValue(IntInit *II) {
+  int64_t Value = II->getValue();
+  // Make sure this bitfield is large enough to hold the integer value...
+  if (Value >= 0) {
+    if (Value & ~((1LL << Size)-1))
+      return 0;
+  } else {
+    if ((Value >> Size) != -1 || ((Value & (1LL << (Size-1))) == 0))
+      return 0;
+  }
+
+  BitsInit *Ret = new BitsInit(Size);
+  for (unsigned i = 0; i != Size; ++i)
+    Ret->setBit(i, new BitInit(Value & (1LL << i)));
+
+  return Ret;
+}
+
+Init *BitsRecTy::convertValue(BitsInit *BI) {
+  // If the number of bits is right, return it.  Otherwise we need to expand or
+  // truncate...
+  if (BI->getNumBits() == Size) return BI;
+  return 0;
+}
+
+Init *BitsRecTy::convertValue(TypedInit *VI) {
+  if (BitsRecTy *BRT = dynamic_cast<BitsRecTy*>(VI->getType()))
+    if (BRT->Size == Size) {
+      BitsInit *Ret = new BitsInit(Size);
+      for (unsigned i = 0; i != Size; ++i)
+        Ret->setBit(i, new VarBitInit(VI, i));
+      return Ret;
+    }
+  if (Size == 1 && dynamic_cast<BitRecTy*>(VI->getType())) {
+    BitsInit *Ret = new BitsInit(1);
+    Ret->setBit(0, VI);
+    return Ret;
+  }
+
+  return 0;
+}
+
+Init *IntRecTy::convertValue(BitInit *BI) {
+  return new IntInit(BI->getValue());
+}
+
+Init *IntRecTy::convertValue(BitsInit *BI) {
+  int64_t Result = 0;
+  for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
+    if (BitInit *Bit = dynamic_cast<BitInit*>(BI->getBit(i))) {
+      Result |= Bit->getValue() << i;
+    } else {
+      return 0;
+    }
+  return new IntInit(Result);
+}
+
+Init *IntRecTy::convertValue(TypedInit *TI) {
+  if (TI->getType()->typeIsConvertibleTo(this))
+    return TI;  // Accept variable if already of the right type!
+  return 0;
+}
+
+Init *StringRecTy::convertValue(UnOpInit *BO) {
+  if (BO->getOpcode() == UnOpInit::CAST) {
+    Init *L = BO->getOperand()->convertInitializerTo(this);
+    if (L == 0) return 0;
+    if (L != BO->getOperand())
+      return new UnOpInit(UnOpInit::CAST, L, new StringRecTy);
+    return BO;
+  }
+
+  return convertValue((TypedInit*)BO);
+}
+
+Init *StringRecTy::convertValue(BinOpInit *BO) {
+  if (BO->getOpcode() == BinOpInit::STRCONCAT) {
+    Init *L = BO->getLHS()->convertInitializerTo(this);
+    Init *R = BO->getRHS()->convertInitializerTo(this);
+    if (L == 0 || R == 0) return 0;
+    if (L != BO->getLHS() || R != BO->getRHS())
+      return new BinOpInit(BinOpInit::STRCONCAT, L, R, new StringRecTy);
+    return BO;
+  }
+  if (BO->getOpcode() == BinOpInit::NAMECONCAT) {
+    if (BO->getType()->getAsString() == getAsString()) {
+      Init *L = BO->getLHS()->convertInitializerTo(this);
+      Init *R = BO->getRHS()->convertInitializerTo(this);
+      if (L == 0 || R == 0) return 0;
+      if (L != BO->getLHS() || R != BO->getRHS())
+        return new BinOpInit(BinOpInit::NAMECONCAT, L, R, new StringRecTy);
+      return BO;
+    }
+  }
+
+  return convertValue((TypedInit*)BO);
+}
+
+
+Init *StringRecTy::convertValue(TypedInit *TI) {
+  if (dynamic_cast<StringRecTy*>(TI->getType()))
+    return TI;  // Accept variable if already of the right type!
+  return 0;
+}
+
+std::string ListRecTy::getAsString() const {
+  return "list<" + Ty->getAsString() + ">";
+}
+
+Init *ListRecTy::convertValue(ListInit *LI) {
+  std::vector<Init*> Elements;
+
+  // Verify that all of the elements of the list are subclasses of the
+  // appropriate class!
+  for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
+    if (Init *CI = LI->getElement(i)->convertInitializerTo(Ty))
+      Elements.push_back(CI);
+    else
+      return 0;
+
+  ListRecTy *LType = dynamic_cast<ListRecTy*>(LI->getType());
+  if (LType == 0) {
+    return 0;
+  }
+
+  return new ListInit(Elements, new ListRecTy(Ty));
+}
+
+Init *ListRecTy::convertValue(TypedInit *TI) {
+  // Ensure that TI is compatible with our class.
+  if (ListRecTy *LRT = dynamic_cast<ListRecTy*>(TI->getType()))
+    if (LRT->getElementType()->typeIsConvertibleTo(getElementType()))
+      return TI;
+  return 0;
+}
+
+Init *CodeRecTy::convertValue(TypedInit *TI) {
+  if (TI->getType()->typeIsConvertibleTo(this))
+    return TI;
+  return 0;
+}
+
+Init *DagRecTy::convertValue(TypedInit *TI) {
+  if (TI->getType()->typeIsConvertibleTo(this))
+    return TI;
+  return 0;
+}
+
+Init *DagRecTy::convertValue(UnOpInit *BO) {
+  if (BO->getOpcode() == UnOpInit::CAST) {
+    Init *L = BO->getOperand()->convertInitializerTo(this);
+    if (L == 0) return 0;
+    if (L != BO->getOperand())
+      return new UnOpInit(UnOpInit::CAST, L, new DagRecTy);
+    return BO;
+  }
+  return 0;
+}
+
+Init *DagRecTy::convertValue(BinOpInit *BO) {
+  if (BO->getOpcode() == BinOpInit::CONCAT) {
+    Init *L = BO->getLHS()->convertInitializerTo(this);
+    Init *R = BO->getRHS()->convertInitializerTo(this);
+    if (L == 0 || R == 0) return 0;
+    if (L != BO->getLHS() || R != BO->getRHS())
+      return new BinOpInit(BinOpInit::CONCAT, L, R, new DagRecTy);
+    return BO;
+  }
+  if (BO->getOpcode() == BinOpInit::NAMECONCAT) {
+    if (BO->getType()->getAsString() == getAsString()) {
+      Init *L = BO->getLHS()->convertInitializerTo(this);
+      Init *R = BO->getRHS()->convertInitializerTo(this);
+      if (L == 0 || R == 0) return 0;
+      if (L != BO->getLHS() || R != BO->getRHS())
+        return new BinOpInit(BinOpInit::CONCAT, L, R, new DagRecTy);
+      return BO;
+    }
+  }
+  return 0;
+}
+
+std::string RecordRecTy::getAsString() const {
+  return Rec->getName();
+}
+
+Init *RecordRecTy::convertValue(DefInit *DI) {
+  // Ensure that DI is a subclass of Rec.
+  if (!DI->getDef()->isSubClassOf(Rec))
+    return 0;
+  return DI;
+}
+
+Init *RecordRecTy::convertValue(TypedInit *TI) {
+  // Ensure that TI is compatible with Rec.
+  if (RecordRecTy *RRT = dynamic_cast<RecordRecTy*>(TI->getType()))
+    if (RRT->getRecord()->isSubClassOf(getRecord()) ||
+        RRT->getRecord() == getRecord())
+      return TI;
+  return 0;
+}
+
+bool RecordRecTy::baseClassOf(const RecordRecTy *RHS) const {
+  if (Rec == RHS->getRecord() || RHS->getRecord()->isSubClassOf(Rec))
+    return true;
+
+  const std::vector<Record*> &SC = Rec->getSuperClasses();
+  for (unsigned i = 0, e = SC.size(); i != e; ++i)
+    if (RHS->getRecord()->isSubClassOf(SC[i]))
+      return true;
+
+  return false;
+}
+
+
+/// resolveTypes - Find a common type that T1 and T2 convert to.
+/// Return 0 if no such type exists.
+///
+RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) {
+  if (!T1->typeIsConvertibleTo(T2)) {
+    if (!T2->typeIsConvertibleTo(T1)) {
+      // If one is a Record type, check superclasses
+      RecordRecTy *RecTy1 = dynamic_cast<RecordRecTy*>(T1);
+      if (RecTy1) {
+        // See if T2 inherits from a type T1 also inherits from
+        const std::vector<Record *> &T1SuperClasses =
+          RecTy1->getRecord()->getSuperClasses();
+        for(std::vector<Record *>::const_iterator i = T1SuperClasses.begin(),
+              iend = T1SuperClasses.end();
+            i != iend;
+            ++i) {
+          RecordRecTy *SuperRecTy1 = new RecordRecTy(*i);
+          RecTy *NewType1 = resolveTypes(SuperRecTy1, T2);
+          if (NewType1 != 0) {
+            if (NewType1 != SuperRecTy1) {
+              delete SuperRecTy1;
+            }
+            return NewType1;
+          }
+        }
+      }
+      RecordRecTy *RecTy2 = dynamic_cast<RecordRecTy*>(T2);
+      if (RecTy2) {
+        // See if T1 inherits from a type T2 also inherits from
+        const std::vector<Record *> &T2SuperClasses =
+          RecTy2->getRecord()->getSuperClasses();
+        for (std::vector<Record *>::const_iterator i = T2SuperClasses.begin(),
+              iend = T2SuperClasses.end();
+            i != iend;
+            ++i) {
+          RecordRecTy *SuperRecTy2 = new RecordRecTy(*i);
+          RecTy *NewType2 = resolveTypes(T1, SuperRecTy2);
+          if (NewType2 != 0) {
+            if (NewType2 != SuperRecTy2) {
+              delete SuperRecTy2;
+            }
+            return NewType2;
+          }
+        }
+      }
+      return 0;
+    }
+    return T2;
+  }
+  return T1;
+}
+
+
+//===----------------------------------------------------------------------===//
+//    Initializer implementations
+//===----------------------------------------------------------------------===//
+
+void Init::dump() const { return print(errs()); }
+
+Init *BitsInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
+  BitsInit *BI = new BitsInit(Bits.size());
+  for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
+    if (Bits[i] >= getNumBits()) {
+      delete BI;
+      return 0;
+    }
+    BI->setBit(i, getBit(Bits[i]));
+  }
+  return BI;
+}
+
+std::string BitsInit::getAsString() const {
+  std::string Result = "{ ";
+  for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
+    if (i) Result += ", ";
+    if (Init *Bit = getBit(e-i-1))
+      Result += Bit->getAsString();
+    else
+      Result += "*";
+  }
+  return Result + " }";
+}
+
+// resolveReferences - If there are any field references that refer to fields
+// that have been filled in, we can propagate the values now.
+//
+Init *BitsInit::resolveReferences(Record &R, const RecordVal *RV) {
+  bool Changed = false;
+  BitsInit *New = new BitsInit(getNumBits());
+
+  for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
+    Init *B;
+    Init *CurBit = getBit(i);
+
+    do {
+      B = CurBit;
+      CurBit = CurBit->resolveReferences(R, RV);
+      Changed |= B != CurBit;
+    } while (B != CurBit);
+    New->setBit(i, CurBit);
+  }
+
+  if (Changed)
+    return New;
+  delete New;
+  return this;
+}
+
+std::string IntInit::getAsString() const {
+  return itostr(Value);
+}
+
+Init *IntInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
+  BitsInit *BI = new BitsInit(Bits.size());
+
+  for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
+    if (Bits[i] >= 64) {
+      delete BI;
+      return 0;
+    }
+    BI->setBit(i, new BitInit(Value & (INT64_C(1) << Bits[i])));
+  }
+  return BI;
+}
+
+Init *ListInit::convertInitListSlice(const std::vector<unsigned> &Elements) {
+  std::vector<Init*> Vals;
+  for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
+    if (Elements[i] >= getSize())
+      return 0;
+    Vals.push_back(getElement(Elements[i]));
+  }
+  return new ListInit(Vals, getType());
+}
+
+Record *ListInit::getElementAsRecord(unsigned i) const {
+  assert(i < Values.size() && "List element index out of range!");
+  DefInit *DI = dynamic_cast<DefInit*>(Values[i]);
+  if (DI == 0) throw "Expected record in list!";
+  return DI->getDef();
+}
+
+Init *ListInit::resolveReferences(Record &R, const RecordVal *RV) {
+  std::vector<Init*> Resolved;
+  Resolved.reserve(getSize());
+  bool Changed = false;
+
+  for (unsigned i = 0, e = getSize(); i != e; ++i) {
+    Init *E;
+    Init *CurElt = getElement(i);
+
+    do {
+      E = CurElt;
+      CurElt = CurElt->resolveReferences(R, RV);
+      Changed |= E != CurElt;
+    } while (E != CurElt);
+    Resolved.push_back(E);
+  }
+
+  if (Changed)
+    return new ListInit(Resolved, getType());
+  return this;
+}
+
+Init *ListInit::resolveListElementReference(Record &R, const RecordVal *IRV,
+                                            unsigned Elt) {
+  if (Elt >= getSize())
+    return 0;  // Out of range reference.
+  Init *E = getElement(Elt);
+  // If the element is set to some value, or if we are resolving a reference
+  // to a specific variable and that variable is explicitly unset, then
+  // replace the VarListElementInit with it.
+  if (IRV || !dynamic_cast<UnsetInit*>(E))
+    return E;
+  return 0;
+}
+
+std::string ListInit::getAsString() const {
+  std::string Result = "[";
+  for (unsigned i = 0, e = Values.size(); i != e; ++i) {
+    if (i) Result += ", ";
+    Result += Values[i]->getAsString();
+  }
+  return Result + "]";
+}
+
+Init *OpInit::resolveBitReference(Record &R, const RecordVal *IRV,
+                                  unsigned Bit) {
+  Init *Folded = Fold(&R, 0);
+
+  if (Folded != this) {
+    TypedInit *Typed = dynamic_cast<TypedInit *>(Folded);
+    if (Typed) {
+      return Typed->resolveBitReference(R, IRV, Bit);
+    }
+  }
+
+  return 0;
+}
+
+Init *OpInit::resolveListElementReference(Record &R, const RecordVal *IRV,
+                                          unsigned Elt) {
+  Init *Folded = Fold(&R, 0);
+
+  if (Folded != this) {
+    TypedInit *Typed = dynamic_cast<TypedInit *>(Folded);
+    if (Typed) {
+      return Typed->resolveListElementReference(R, IRV, Elt);
+    }
+  }
+
+  return 0;
+}
+
+Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
+  switch (getOpcode()) {
+  default: assert(0 && "Unknown unop");
+  case CAST: {
+    if (getType()->getAsString() == "string") {
+      StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
+      if (LHSs) {
+        return LHSs;
+      }
+
+      DefInit *LHSd = dynamic_cast<DefInit*>(LHS);
+      if (LHSd) {
+        return new StringInit(LHSd->getDef()->getName());
+      }
+    } else {
+      StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
+      if (LHSs) {
+        std::string Name = LHSs->getValue();
+
+        // From TGParser::ParseIDValue
+        if (CurRec) {
+          if (const RecordVal *RV = CurRec->getValue(Name)) {
+            if (RV->getType() != getType()) {
+              throw "type mismatch in nameconcat";
+            }
+            return new VarInit(Name, RV->getType());
+          }
+
+          std::string TemplateArgName = CurRec->getName()+":"+Name;
+          if (CurRec->isTemplateArg(TemplateArgName)) {
+            const RecordVal *RV = CurRec->getValue(TemplateArgName);
+            assert(RV && "Template arg doesn't exist??");
+
+            if (RV->getType() != getType()) {
+              throw "type mismatch in nameconcat";
+            }
+
+            return new VarInit(TemplateArgName, RV->getType());
+          }
+        }
+
+        if (CurMultiClass) {
+          std::string MCName = CurMultiClass->Rec.getName()+"::"+Name;
+          if (CurMultiClass->Rec.isTemplateArg(MCName)) {
+            const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
+            assert(RV && "Template arg doesn't exist??");
+
+            if (RV->getType() != getType()) {
+              throw "type mismatch in nameconcat";
+            }
+
+            return new VarInit(MCName, RV->getType());
+          }
+        }
+
+        if (Record *D = Records.getDef(Name))
+          return new DefInit(D);
+
+        errs() << "Variable not defined: '" + Name + "'\n";
+        assert(0 && "Variable not found");
+        return 0;
+      }
+    }
+    break;
+  }
+  case CAR: {
+    ListInit *LHSl = dynamic_cast<ListInit*>(LHS);
+    if (LHSl) {
+      if (LHSl->getSize() == 0) {
+        assert(0 && "Empty list in car");
+        return 0;
+      }
+      return LHSl->getElement(0);
+    }
+    break;
+  }
+  case CDR: {
+    ListInit *LHSl = dynamic_cast<ListInit*>(LHS);
+    if (LHSl) {
+      if (LHSl->getSize() == 0) {
+        assert(0 && "Empty list in cdr");
+        return 0;
+      }
+      ListInit *Result = new ListInit(LHSl->begin()+1, LHSl->end(),
+                                      LHSl->getType());
+      return Result;
+    }
+    break;
+  }
+  case LNULL: {
+    ListInit *LHSl = dynamic_cast<ListInit*>(LHS);
+    if (LHSl) {
+      if (LHSl->getSize() == 0) {
+        return new IntInit(1);
+      } else {
+        return new IntInit(0);
+      }
+    }
+    StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
+    if (LHSs) {
+      if (LHSs->getValue().empty()) {
+        return new IntInit(1);
+      } else {
+        return new IntInit(0);
+      }
+    }
+
+    break;
+  }
+  }
+  return this;
+}
+
+Init *UnOpInit::resolveReferences(Record &R, const RecordVal *RV) {
+  Init *lhs = LHS->resolveReferences(R, RV);
+
+  if (LHS != lhs)
+    return (new UnOpInit(getOpcode(), lhs, getType()))->Fold(&R, 0);
+  return Fold(&R, 0);
+}
+
+std::string UnOpInit::getAsString() const {
+  std::string Result;
+  switch (Opc) {
+  case CAST: Result = "!cast<" + getType()->getAsString() + ">"; break;
+  case CAR: Result = "!car"; break;
+  case CDR: Result = "!cdr"; break;
+  case LNULL: Result = "!null"; break;
+  }
+  return Result + "(" + LHS->getAsString() + ")";
+}
+
+RecTy *UnOpInit::getFieldType(const std::string &FieldName) const {
+  switch (getOpcode()) {
+  default: assert(0 && "Unknown unop");
+  case CAST: {
+    RecordRecTy *RecordType = dynamic_cast<RecordRecTy *>(getType());
+    if (RecordType) {
+      RecordVal *Field = RecordType->getRecord()->getValue(FieldName);
+      if (Field) {
+        return Field->getType();
+      }
+    }
+    break;
+  }
+  }
+  return 0;
+}
+
+Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
+  switch (getOpcode()) {
+  default: assert(0 && "Unknown binop");
+  case CONCAT: {
+    DagInit *LHSs = dynamic_cast<DagInit*>(LHS);
+    DagInit *RHSs = dynamic_cast<DagInit*>(RHS);
+    if (LHSs && RHSs) {
+      DefInit *LOp = dynamic_cast<DefInit*>(LHSs->getOperator());
+      DefInit *ROp = dynamic_cast<DefInit*>(RHSs->getOperator());
+      if (LOp == 0 || ROp == 0 || LOp->getDef() != ROp->getDef())
+        throw "Concated Dag operators do not match!";
+      std::vector<Init*> Args;
+      std::vector<std::string> ArgNames;
+      for (unsigned i = 0, e = LHSs->getNumArgs(); i != e; ++i) {
+        Args.push_back(LHSs->getArg(i));
+        ArgNames.push_back(LHSs->getArgName(i));
+      }
+      for (unsigned i = 0, e = RHSs->getNumArgs(); i != e; ++i) {
+        Args.push_back(RHSs->getArg(i));
+        ArgNames.push_back(RHSs->getArgName(i));
+      }
+      return new DagInit(LHSs->getOperator(), "", Args, ArgNames);
+    }
+    break;
+  }
+  case STRCONCAT: {
+    StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
+    StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
+    if (LHSs && RHSs)
+      return new StringInit(LHSs->getValue() + RHSs->getValue());
+    break;
+  }
+  case NAMECONCAT: {
+    StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
+    StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
+    if (LHSs && RHSs) {
+      std::string Name(LHSs->getValue() + RHSs->getValue());
+
+      // From TGParser::ParseIDValue
+      if (CurRec) {
+        if (const RecordVal *RV = CurRec->getValue(Name)) {
+          if (RV->getType() != getType()) {
+            throw "type mismatch in nameconcat";
+          }
+          return new VarInit(Name, RV->getType());
+        }
+
+        std::string TemplateArgName = CurRec->getName()+":"+Name;
+        if (CurRec->isTemplateArg(TemplateArgName)) {
+          const RecordVal *RV = CurRec->getValue(TemplateArgName);
+          assert(RV && "Template arg doesn't exist??");
+
+          if (RV->getType() != getType()) {
+            throw "type mismatch in nameconcat";
+          }
+
+          return new VarInit(TemplateArgName, RV->getType());
+        }
+      }
+
+      if (CurMultiClass) {
+        std::string MCName = CurMultiClass->Rec.getName()+"::"+Name;
+        if (CurMultiClass->Rec.isTemplateArg(MCName)) {
+          const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
+          assert(RV && "Template arg doesn't exist??");
+
+          if (RV->getType() != getType()) {
+            throw "type mismatch in nameconcat";
+          }
+
+          return new VarInit(MCName, RV->getType());
+        }
+      }
+
+      if (Record *D = Records.getDef(Name))
+        return new DefInit(D);
+
+      errs() << "Variable not defined in !nameconcat: '" + Name + "'\n";
+      assert(0 && "Variable not found in !nameconcat");
+      return 0;
+    }
+    break;
+  }
+  case EQ: {
+    // try to fold eq comparison for 'bit' and 'int', otherwise fallback
+    // to string objects.
+    IntInit* L =
+      dynamic_cast<IntInit*>(LHS->convertInitializerTo(new IntRecTy()));
+    IntInit* R =
+      dynamic_cast<IntInit*>(RHS->convertInitializerTo(new IntRecTy()));
+
+    if (L && R)
+      return new IntInit(L->getValue() == R->getValue());
+
+    StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
+    StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
+
+    // Make sure we've resolved
+    if (LHSs && RHSs)
+      return new IntInit(LHSs->getValue() == RHSs->getValue());
+
+    break;
+  }
+  case SHL:
+  case SRA:
+  case SRL: {
+    IntInit *LHSi = dynamic_cast<IntInit*>(LHS);
+    IntInit *RHSi = dynamic_cast<IntInit*>(RHS);
+    if (LHSi && RHSi) {
+      int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue();
+      int64_t Result;
+      switch (getOpcode()) {
+      default: assert(0 && "Bad opcode!");
+      case SHL: Result = LHSv << RHSv; break;
+      case SRA: Result = LHSv >> RHSv; break;
+      case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break;
+      }
+      return new IntInit(Result);
+    }
+    break;
+  }
+  }
+  return this;
+}
+
+Init *BinOpInit::resolveReferences(Record &R, const RecordVal *RV) {
+  Init *lhs = LHS->resolveReferences(R, RV);
+  Init *rhs = RHS->resolveReferences(R, RV);
+
+  if (LHS != lhs || RHS != rhs)
+    return (new BinOpInit(getOpcode(), lhs, rhs, getType()))->Fold(&R, 0);
+  return Fold(&R, 0);
+}
+
+std::string BinOpInit::getAsString() const {
+  std::string Result;
+  switch (Opc) {
+  case CONCAT: Result = "!con"; break;
+  case SHL: Result = "!shl"; break;
+  case SRA: Result = "!sra"; break;
+  case SRL: Result = "!srl"; break;
+  case EQ: Result = "!eq"; break;
+  case STRCONCAT: Result = "!strconcat"; break;
+  case NAMECONCAT:
+    Result = "!nameconcat<" + getType()->getAsString() + ">"; break;
+  }
+  return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
+}
+
+static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
+                           Record *CurRec, MultiClass *CurMultiClass);
+
+static Init *EvaluateOperation(OpInit *RHSo, Init *LHS, Init *Arg,
+                               RecTy *Type, Record *CurRec,
+                               MultiClass *CurMultiClass) {
+  std::vector<Init *> NewOperands;
+
+  TypedInit *TArg = dynamic_cast<TypedInit*>(Arg);
+
+  // If this is a dag, recurse
+  if (TArg && TArg->getType()->getAsString() == "dag") {
+    Init *Result = ForeachHelper(LHS, Arg, RHSo, Type,
+                                 CurRec, CurMultiClass);
+    if (Result != 0) {
+      return Result;
+    } else {
+      return 0;
+    }
+  }
+
+  for (int i = 0; i < RHSo->getNumOperands(); ++i) {
+    OpInit *RHSoo = dynamic_cast<OpInit*>(RHSo->getOperand(i));
+
+    if (RHSoo) {
+      Init *Result = EvaluateOperation(RHSoo, LHS, Arg,
+                                       Type, CurRec, CurMultiClass);
+      if (Result != 0) {
+        NewOperands.push_back(Result);
+      } else {
+        NewOperands.push_back(Arg);
+      }
+    } else if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
+      NewOperands.push_back(Arg);
+    } else {
+      NewOperands.push_back(RHSo->getOperand(i));
+    }
+  }
+
+  // Now run the operator and use its result as the new leaf
+  OpInit *NewOp = RHSo->clone(NewOperands);
+  Init *NewVal = NewOp->Fold(CurRec, CurMultiClass);
+  if (NewVal != NewOp) {
+    delete NewOp;
+    return NewVal;
+  }
+  return 0;
+}
+
+static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
+                           Record *CurRec, MultiClass *CurMultiClass) {
+  DagInit *MHSd = dynamic_cast<DagInit*>(MHS);
+  ListInit *MHSl = dynamic_cast<ListInit*>(MHS);
+
+  DagRecTy *DagType = dynamic_cast<DagRecTy*>(Type);
+  ListRecTy *ListType = dynamic_cast<ListRecTy*>(Type);
+
+  OpInit *RHSo = dynamic_cast<OpInit*>(RHS);
+
+  if (!RHSo) {
+    errs() << "!foreach requires an operator\n";
+    assert(0 && "No operator for !foreach");
+  }
+
+  TypedInit *LHSt = dynamic_cast<TypedInit*>(LHS);
+
+  if (!LHSt) {
+    errs() << "!foreach requires typed variable\n";
+    assert(0 && "No typed variable for !foreach");
+  }
+
+  if ((MHSd && DagType) || (MHSl && ListType)) {
+    if (MHSd) {
+      Init *Val = MHSd->getOperator();
+      Init *Result = EvaluateOperation(RHSo, LHS, Val,
+                                       Type, CurRec, CurMultiClass);
+      if (Result != 0) {
+        Val = Result;
+      }
+
+      std::vector<std::pair<Init *, std::string> > args;
+      for (unsigned int i = 0; i < MHSd->getNumArgs(); ++i) {
+        Init *Arg;
+        std::string ArgName;
+        Arg = MHSd->getArg(i);
+        ArgName = MHSd->getArgName(i);
+
+        // Process args
+        Init *Result = EvaluateOperation(RHSo, LHS, Arg, Type,
+                                         CurRec, CurMultiClass);
+        if (Result != 0) {
+          Arg = Result;
+        }
+
+        // TODO: Process arg names
+        args.push_back(std::make_pair(Arg, ArgName));
+      }
+
+      return new DagInit(Val, "", args);
+    }
+    if (MHSl) {
+      std::vector<Init *> NewOperands;
+      std::vector<Init *> NewList(MHSl->begin(), MHSl->end());
+
+      for (ListInit::iterator li = NewList.begin(),
+             liend = NewList.end();
+           li != liend;
+           ++li) {
+        Init *Item = *li;
+        NewOperands.clear();
+        for(int i = 0; i < RHSo->getNumOperands(); ++i) {
+          // First, replace the foreach variable with the list item
+          if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
+            NewOperands.push_back(Item);
+          } else {
+            NewOperands.push_back(RHSo->getOperand(i));
+          }
+        }
+
+        // Now run the operator and use its result as the new list item
+        OpInit *NewOp = RHSo->clone(NewOperands);
+        Init *NewItem = NewOp->Fold(CurRec, CurMultiClass);
+        if (NewItem != NewOp) {
+          *li = NewItem;
+          delete NewOp;
+        }
+      }
+      return new ListInit(NewList, MHSl->getType());
+    }
+  }
+  return 0;
+}
+
+Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
+  switch (getOpcode()) {
+  default: assert(0 && "Unknown binop");
+  case SUBST: {
+    DefInit *LHSd = dynamic_cast<DefInit*>(LHS);
+    VarInit *LHSv = dynamic_cast<VarInit*>(LHS);
+    StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
+
+    DefInit *MHSd = dynamic_cast<DefInit*>(MHS);
+    VarInit *MHSv = dynamic_cast<VarInit*>(MHS);
+    StringInit *MHSs = dynamic_cast<StringInit*>(MHS);
+
+    DefInit *RHSd = dynamic_cast<DefInit*>(RHS);
+    VarInit *RHSv = dynamic_cast<VarInit*>(RHS);
+    StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
+
+    if ((LHSd && MHSd && RHSd)
+        || (LHSv && MHSv && RHSv)
+        || (LHSs && MHSs && RHSs)) {
+      if (RHSd) {
+        Record *Val = RHSd->getDef();
+        if (LHSd->getAsString() == RHSd->getAsString()) {
+          Val = MHSd->getDef();
+        }
+        return new DefInit(Val);
+      }
+      if (RHSv) {
+        std::string Val = RHSv->getName();
+        if (LHSv->getAsString() == RHSv->getAsString()) {
+          Val = MHSv->getName();
+        }
+        return new VarInit(Val, getType());
+      }
+      if (RHSs) {
+        std::string Val = RHSs->getValue();
+
+        std::string::size_type found;
+        std::string::size_type idx = 0;
+        do {
+          found = Val.find(LHSs->getValue(), idx);
+          if (found != std::string::npos) {
+            Val.replace(found, LHSs->getValue().size(), MHSs->getValue());
+          }
+          idx = found +  MHSs->getValue().size();
+        } while (found != std::string::npos);
+
+        return new StringInit(Val);
+      }
+    }
+    break;
+  }
+
+  case FOREACH: {
+    Init *Result = ForeachHelper(LHS, MHS, RHS, getType(),
+                                 CurRec, CurMultiClass);
+    if (Result != 0) {
+      return Result;
+    }
+    break;
+  }
+
+  case IF: {
+    IntInit *LHSi = dynamic_cast<IntInit*>(LHS);
+    if (Init *I = LHS->convertInitializerTo(new IntRecTy()))
+      LHSi = dynamic_cast<IntInit*>(I);
+    if (LHSi) {
+      if (LHSi->getValue()) {
+        return MHS;
+      } else {
+        return RHS;
+      }
+    }
+    break;
+  }
+  }
+
+  return this;
+}
+
+Init *TernOpInit::resolveReferences(Record &R, const RecordVal *RV) {
+  Init *lhs = LHS->resolveReferences(R, RV);
+
+  if (Opc == IF && lhs != LHS) {
+    IntInit *Value = dynamic_cast<IntInit*>(lhs);
+    if (Init *I = lhs->convertInitializerTo(new IntRecTy()))
+      Value = dynamic_cast<IntInit*>(I);
+    if (Value != 0) {
+      // Short-circuit
+      if (Value->getValue()) {
+        Init *mhs = MHS->resolveReferences(R, RV);
+        return (new TernOpInit(getOpcode(), lhs, mhs,
+                               RHS, getType()))->Fold(&R, 0);
+      } else {
+        Init *rhs = RHS->resolveReferences(R, RV);
+        return (new TernOpInit(getOpcode(), lhs, MHS,
+                               rhs, getType()))->Fold(&R, 0);
+      }
+    }
+  }
+
+  Init *mhs = MHS->resolveReferences(R, RV);
+  Init *rhs = RHS->resolveReferences(R, RV);
+
+  if (LHS != lhs || MHS != mhs || RHS != rhs)
+    return (new TernOpInit(getOpcode(), lhs, mhs, rhs, getType()))->Fold(&R, 0);
+  return Fold(&R, 0);
+}
+
+std::string TernOpInit::getAsString() const {
+  std::string Result;
+  switch (Opc) {
+  case SUBST: Result = "!subst"; break;
+  case FOREACH: Result = "!foreach"; break;
+  case IF: Result = "!if"; break;
+ }
+  return Result + "(" + LHS->getAsString() + ", " + MHS->getAsString() + ", "
+    + RHS->getAsString() + ")";
+}
+
+Init *TypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
+  BitsRecTy *T = dynamic_cast<BitsRecTy*>(getType());
+  if (T == 0) return 0;  // Cannot subscript a non-bits variable...
+  unsigned NumBits = T->getNumBits();
+
+  BitsInit *BI = new BitsInit(Bits.size());
+  for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
+    if (Bits[i] >= NumBits) {
+      delete BI;
+      return 0;
+    }
+    BI->setBit(i, new VarBitInit(this, Bits[i]));
+  }
+  return BI;
+}
+
+Init *TypedInit::convertInitListSlice(const std::vector<unsigned> &Elements) {
+  ListRecTy *T = dynamic_cast<ListRecTy*>(getType());
+  if (T == 0) return 0;  // Cannot subscript a non-list variable...
+
+  if (Elements.size() == 1)
+    return new VarListElementInit(this, Elements[0]);
+
+  std::vector<Init*> ListInits;
+  ListInits.reserve(Elements.size());
+  for (unsigned i = 0, e = Elements.size(); i != e; ++i)
+    ListInits.push_back(new VarListElementInit(this, Elements[i]));
+  return new ListInit(ListInits, T);
+}
+
+
+Init *VarInit::resolveBitReference(Record &R, const RecordVal *IRV,
+                                   unsigned Bit) {
+  if (R.isTemplateArg(getName())) return 0;
+  if (IRV && IRV->getName() != getName()) return 0;
+
+  RecordVal *RV = R.getValue(getName());
+  assert(RV && "Reference to a non-existent variable?");
+  assert(dynamic_cast<BitsInit*>(RV->getValue()));
+  BitsInit *BI = (BitsInit*)RV->getValue();
+
+  assert(Bit < BI->getNumBits() && "Bit reference out of range!");
+  Init *B = BI->getBit(Bit);
+
+  // If the bit is set to some value, or if we are resolving a reference to a
+  // specific variable and that variable is explicitly unset, then replace the
+  // VarBitInit with it.
+  if (IRV || !dynamic_cast<UnsetInit*>(B))
+    return B;
+  return 0;
+}
+
+Init *VarInit::resolveListElementReference(Record &R, const RecordVal *IRV,
+                                           unsigned Elt) {
+  if (R.isTemplateArg(getName())) return 0;
+  if (IRV && IRV->getName() != getName()) return 0;
+
+  RecordVal *RV = R.getValue(getName());
+  assert(RV && "Reference to a non-existent variable?");
+  ListInit *LI = dynamic_cast<ListInit*>(RV->getValue());
+  if (!LI) {
+    VarInit *VI = dynamic_cast<VarInit*>(RV->getValue());
+    assert(VI && "Invalid list element!");
+    return new VarListElementInit(VI, Elt);
+  }
+
+  if (Elt >= LI->getSize())
+    return 0;  // Out of range reference.
+  Init *E = LI->getElement(Elt);
+  // If the element is set to some value, or if we are resolving a reference
+  // to a specific variable and that variable is explicitly unset, then
+  // replace the VarListElementInit with it.
+  if (IRV || !dynamic_cast<UnsetInit*>(E))
+    return E;
+  return 0;
+}
+
+
+RecTy *VarInit::getFieldType(const std::string &FieldName) const {
+  if (RecordRecTy *RTy = dynamic_cast<RecordRecTy*>(getType()))
+    if (const RecordVal *RV = RTy->getRecord()->getValue(FieldName))
+      return RV->getType();
+  return 0;
+}
+
+Init *VarInit::getFieldInit(Record &R, const RecordVal *RV,
+                            const std::string &FieldName) const {
+  if (dynamic_cast<RecordRecTy*>(getType()))
+    if (const RecordVal *Val = R.getValue(VarName)) {
+      if (RV != Val && (RV || dynamic_cast<UnsetInit*>(Val->getValue())))
+        return 0;
+      Init *TheInit = Val->getValue();
+      assert(TheInit != this && "Infinite loop detected!");
+      if (Init *I = TheInit->getFieldInit(R, RV, FieldName))
+        return I;
+      else
+        return 0;
+    }
+  return 0;
+}
+
+/// resolveReferences - This method is used by classes that refer to other
+/// variables which may not be defined at the time the expression is formed.
+/// If a value is set for the variable later, this method will be called on
+/// users of the value to allow the value to propagate out.
+///
+Init *VarInit::resolveReferences(Record &R, const RecordVal *RV) {
+  if (RecordVal *Val = R.getValue(VarName))
+    if (RV == Val || (RV == 0 && !dynamic_cast<UnsetInit*>(Val->getValue())))
+      return Val->getValue();
+  return this;
+}
+
+std::string VarBitInit::getAsString() const {
+   return TI->getAsString() + "{" + utostr(Bit) + "}";
+}
+
+Init *VarBitInit::resolveReferences(Record &R, const RecordVal *RV) {
+  if (Init *I = getVariable()->resolveBitReference(R, RV, getBitNum()))
+    return I;
+  return this;
+}
+
+std::string VarListElementInit::getAsString() const {
+  return TI->getAsString() + "[" + utostr(Element) + "]";
+}
+
+Init *VarListElementInit::resolveReferences(Record &R, const RecordVal *RV) {
+  if (Init *I = getVariable()->resolveListElementReference(R, RV,
+                                                           getElementNum()))
+    return I;
+  return this;
+}
+
+Init *VarListElementInit::resolveBitReference(Record &R, const RecordVal *RV,
+                                              unsigned Bit) {
+  // FIXME: This should be implemented, to support references like:
+  // bit B = AA[0]{1};
+  return 0;
+}
+
+Init *VarListElementInit::
+resolveListElementReference(Record &R, const RecordVal *RV, unsigned Elt) {
+  // FIXME: This should be implemented, to support references like:
+  // int B = AA[0][1];
+  return 0;
+}
+
+RecTy *DefInit::getFieldType(const std::string &FieldName) const {
+  if (const RecordVal *RV = Def->getValue(FieldName))
+    return RV->getType();
+  return 0;
+}
+
+Init *DefInit::getFieldInit(Record &R, const RecordVal *RV,
+                            const std::string &FieldName) const {
+  return Def->getValue(FieldName)->getValue();
+}
+
+
+std::string DefInit::getAsString() const {
+  return Def->getName();
+}
+
+Init *FieldInit::resolveBitReference(Record &R, const RecordVal *RV,
+                                     unsigned Bit) {
+  if (Init *BitsVal = Rec->getFieldInit(R, RV, FieldName))
+    if (BitsInit *BI = dynamic_cast<BitsInit*>(BitsVal)) {
+      assert(Bit < BI->getNumBits() && "Bit reference out of range!");
+      Init *B = BI->getBit(Bit);
+
+      if (dynamic_cast<BitInit*>(B))  // If the bit is set...
+        return B;                     // Replace the VarBitInit with it.
+    }
+  return 0;
+}
+
+Init *FieldInit::resolveListElementReference(Record &R, const RecordVal *RV,
+                                             unsigned Elt) {
+  if (Init *ListVal = Rec->getFieldInit(R, RV, FieldName))
+    if (ListInit *LI = dynamic_cast<ListInit*>(ListVal)) {
+      if (Elt >= LI->getSize()) return 0;
+      Init *E = LI->getElement(Elt);
+
+      // If the element is set to some value, or if we are resolving a
+      // reference to a specific variable and that variable is explicitly
+      // unset, then replace the VarListElementInit with it.
+      if (RV || !dynamic_cast<UnsetInit*>(E))
+        return E;
+    }
+  return 0;
+}
+
+Init *FieldInit::resolveReferences(Record &R, const RecordVal *RV) {
+  Init *NewRec = RV ? Rec->resolveReferences(R, RV) : Rec;
+
+  Init *BitsVal = NewRec->getFieldInit(R, RV, FieldName);
+  if (BitsVal) {
+    Init *BVR = BitsVal->resolveReferences(R, RV);
+    return BVR->isComplete() ? BVR : this;
+  }
+
+  if (NewRec != Rec) {
+    return new FieldInit(NewRec, FieldName);
+  }
+  return this;
+}
+
+Init *DagInit::resolveReferences(Record &R, const RecordVal *RV) {
+  std::vector<Init*> NewArgs;
+  for (unsigned i = 0, e = Args.size(); i != e; ++i)
+    NewArgs.push_back(Args[i]->resolveReferences(R, RV));
+
+  Init *Op = Val->resolveReferences(R, RV);
+
+  if (Args != NewArgs || Op != Val)
+    return new DagInit(Op, ValName, NewArgs, ArgNames);
+
+  return this;
+}
+
+
+std::string DagInit::getAsString() const {
+  std::string Result = "(" + Val->getAsString();
+  if (!ValName.empty())
+    Result += ":" + ValName;
+  if (Args.size()) {
+    Result += " " + Args[0]->getAsString();
+    if (!ArgNames[0].empty()) Result += ":$" + ArgNames[0];
+    for (unsigned i = 1, e = Args.size(); i != e; ++i) {
+      Result += ", " + Args[i]->getAsString();
+      if (!ArgNames[i].empty()) Result += ":$" + ArgNames[i];
+    }
+  }
+  return Result + ")";
+}
+
+
+//===----------------------------------------------------------------------===//
+//    Other implementations
+//===----------------------------------------------------------------------===//
+
+RecordVal::RecordVal(const std::string &N, RecTy *T, unsigned P)
+  : Name(N), Ty(T), Prefix(P) {
+  Value = Ty->convertValue(new UnsetInit());
+  assert(Value && "Cannot create unset value for current type!");
+}
+
+void RecordVal::dump() const { errs() << *this; }
+
+void RecordVal::print(raw_ostream &OS, bool PrintSem) const {
+  if (getPrefix()) OS << "field ";
+  OS << *getType() << " " << getName();
+
+  if (getValue())
+    OS << " = " << *getValue();
+
+  if (PrintSem) OS << ";\n";
+}
+
+unsigned Record::LastID = 0;
+
+void Record::setName(const std::string &Name) {
+  if (Records.getDef(getName()) == this) {
+    Records.removeDef(getName());
+    this->Name = Name;
+    Records.addDef(this);
+  } else {
+    Records.removeClass(getName());
+    this->Name = Name;
+    Records.addClass(this);
+  }
+}
+
+/// resolveReferencesTo - If anything in this record refers to RV, replace the
+/// reference to RV with the RHS of RV.  If RV is null, we resolve all possible
+/// references.
+void Record::resolveReferencesTo(const RecordVal *RV) {
+  for (unsigned i = 0, e = Values.size(); i != e; ++i) {
+    if (Init *V = Values[i].getValue())
+      Values[i].setValue(V->resolveReferences(*this, RV));
+  }
+}
+
+void Record::dump() const { errs() << *this; }
+
+raw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) {
+  OS << R.getName();
+
+  const std::vector<std::string> &TArgs = R.getTemplateArgs();
+  if (!TArgs.empty()) {
+    OS << "<";
+    for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
+      if (i) OS << ", ";
+      const RecordVal *RV = R.getValue(TArgs[i]);
+      assert(RV && "Template argument record not found??");
+      RV->print(OS, false);
+    }
+    OS << ">";
+  }
+
+  OS << " {";
+  const std::vector<Record*> &SC = R.getSuperClasses();
+  if (!SC.empty()) {
+    OS << "\t//";
+    for (unsigned i = 0, e = SC.size(); i != e; ++i)
+      OS << " " << SC[i]->getName();
+  }
+  OS << "\n";
+
+  const std::vector<RecordVal> &Vals = R.getValues();
+  for (unsigned i = 0, e = Vals.size(); i != e; ++i)
+    if (Vals[i].getPrefix() && !R.isTemplateArg(Vals[i].getName()))
+      OS << Vals[i];
+  for (unsigned i = 0, e = Vals.size(); i != e; ++i)
+    if (!Vals[i].getPrefix() && !R.isTemplateArg(Vals[i].getName()))
+      OS << Vals[i];
+
+  return OS << "}\n";
+}
+
+/// getValueInit - Return the initializer for a value with the specified name,
+/// or throw an exception if the field does not exist.
+///
+Init *Record::getValueInit(StringRef FieldName) const {
+  const RecordVal *R = getValue(FieldName);
+  if (R == 0 || R->getValue() == 0)
+    throw "Record `" + getName() + "' does not have a field named `" +
+      FieldName.str() + "'!\n";
+  return R->getValue();
+}
+
+
+/// getValueAsString - This method looks up the specified field and returns its
+/// value as a string, throwing an exception if the field does not exist or if
+/// the value is not a string.
+///
+std::string Record::getValueAsString(StringRef FieldName) const {
+  const RecordVal *R = getValue(FieldName);
+  if (R == 0 || R->getValue() == 0)
+    throw "Record `" + getName() + "' does not have a field named `" +
+          FieldName.str() + "'!\n";
+
+  if (const StringInit *SI = dynamic_cast<const StringInit*>(R->getValue()))
+    return SI->getValue();
+  throw "Record `" + getName() + "', field `" + FieldName.str() +
+        "' does not have a string initializer!";
+}
+
+/// getValueAsBitsInit - This method looks up the specified field and returns
+/// its value as a BitsInit, throwing an exception if the field does not exist
+/// or if the value is not the right type.
+///
+BitsInit *Record::getValueAsBitsInit(StringRef FieldName) const {
+  const RecordVal *R = getValue(FieldName);
+  if (R == 0 || R->getValue() == 0)
+    throw "Record `" + getName() + "' does not have a field named `" +
+          FieldName.str() + "'!\n";
+
+  if (BitsInit *BI = dynamic_cast<BitsInit*>(R->getValue()))
+    return BI;
+  throw "Record `" + getName() + "', field `" + FieldName.str() +
+        "' does not have a BitsInit initializer!";
+}
+
+/// getValueAsListInit - This method looks up the specified field and returns
+/// its value as a ListInit, throwing an exception if the field does not exist
+/// or if the value is not the right type.
+///
+ListInit *Record::getValueAsListInit(StringRef FieldName) const {
+  const RecordVal *R = getValue(FieldName);
+  if (R == 0 || R->getValue() == 0)
+    throw "Record `" + getName() + "' does not have a field named `" +
+          FieldName.str() + "'!\n";
+
+  if (ListInit *LI = dynamic_cast<ListInit*>(R->getValue()))
+    return LI;
+  throw "Record `" + getName() + "', field `" + FieldName.str() +
+        "' does not have a list initializer!";
+}
+
+/// getValueAsListOfDefs - This method looks up the specified field and returns
+/// its value as a vector of records, throwing an exception if the field does
+/// not exist or if the value is not the right type.
+///
+std::vector<Record*>
+Record::getValueAsListOfDefs(StringRef FieldName) const {
+  ListInit *List = getValueAsListInit(FieldName);
+  std::vector<Record*> Defs;
+  for (unsigned i = 0; i < List->getSize(); i++) {
+    if (DefInit *DI = dynamic_cast<DefInit*>(List->getElement(i))) {
+      Defs.push_back(DI->getDef());
+    } else {
+      throw "Record `" + getName() + "', field `" + FieldName.str() +
+            "' list is not entirely DefInit!";
+    }
+  }
+  return Defs;
+}
+
+/// getValueAsInt - This method looks up the specified field and returns its
+/// value as an int64_t, throwing an exception if the field does not exist or if
+/// the value is not the right type.
+///
+int64_t Record::getValueAsInt(StringRef FieldName) const {
+  const RecordVal *R = getValue(FieldName);
+  if (R == 0 || R->getValue() == 0)
+    throw "Record `" + getName() + "' does not have a field named `" +
+          FieldName.str() + "'!\n";
+
+  if (IntInit *II = dynamic_cast<IntInit*>(R->getValue()))
+    return II->getValue();
+  throw "Record `" + getName() + "', field `" + FieldName.str() +
+        "' does not have an int initializer!";
+}
+
+/// getValueAsListOfInts - This method looks up the specified field and returns
+/// its value as a vector of integers, throwing an exception if the field does
+/// not exist or if the value is not the right type.
+///
+std::vector<int64_t>
+Record::getValueAsListOfInts(StringRef FieldName) const {
+  ListInit *List = getValueAsListInit(FieldName);
+  std::vector<int64_t> Ints;
+  for (unsigned i = 0; i < List->getSize(); i++) {
+    if (IntInit *II = dynamic_cast<IntInit*>(List->getElement(i))) {
+      Ints.push_back(II->getValue());
+    } else {
+      throw "Record `" + getName() + "', field `" + FieldName.str() +
+            "' does not have a list of ints initializer!";
+    }
+  }
+  return Ints;
+}
+
+/// getValueAsDef - This method looks up the specified field and returns its
+/// value as a Record, throwing an exception if the field does not exist or if
+/// the value is not the right type.
+///
+Record *Record::getValueAsDef(StringRef FieldName) const {
+  const RecordVal *R = getValue(FieldName);
+  if (R == 0 || R->getValue() == 0)
+    throw "Record `" + getName() + "' does not have a field named `" +
+      FieldName.str() + "'!\n";
+
+  if (DefInit *DI = dynamic_cast<DefInit*>(R->getValue()))
+    return DI->getDef();
+  throw "Record `" + getName() + "', field `" + FieldName.str() +
+        "' does not have a def initializer!";
+}
+
+/// getValueAsBit - This method looks up the specified field and returns its
+/// value as a bit, throwing an exception if the field does not exist or if
+/// the value is not the right type.
+///
+bool Record::getValueAsBit(StringRef FieldName) const {
+  const RecordVal *R = getValue(FieldName);
+  if (R == 0 || R->getValue() == 0)
+    throw "Record `" + getName() + "' does not have a field named `" +
+      FieldName.str() + "'!\n";
+
+  if (BitInit *BI = dynamic_cast<BitInit*>(R->getValue()))
+    return BI->getValue();
+  throw "Record `" + getName() + "', field `" + FieldName.str() +
+        "' does not have a bit initializer!";
+}
+
+/// getValueAsDag - This method looks up the specified field and returns its
+/// value as an Dag, throwing an exception if the field does not exist or if
+/// the value is not the right type.
+///
+DagInit *Record::getValueAsDag(StringRef FieldName) const {
+  const RecordVal *R = getValue(FieldName);
+  if (R == 0 || R->getValue() == 0)
+    throw "Record `" + getName() + "' does not have a field named `" +
+      FieldName.str() + "'!\n";
+
+  if (DagInit *DI = dynamic_cast<DagInit*>(R->getValue()))
+    return DI;
+  throw "Record `" + getName() + "', field `" + FieldName.str() +
+        "' does not have a dag initializer!";
+}
+
+std::string Record::getValueAsCode(StringRef FieldName) const {
+  const RecordVal *R = getValue(FieldName);
+  if (R == 0 || R->getValue() == 0)
+    throw "Record `" + getName() + "' does not have a field named `" +
+      FieldName.str() + "'!\n";
+
+  if (const CodeInit *CI = dynamic_cast<const CodeInit*>(R->getValue()))
+    return CI->getValue();
+  throw "Record `" + getName() + "', field `" + FieldName.str() +
+    "' does not have a code initializer!";
+}
+
+
+void MultiClass::dump() const {
+  errs() << "Record:\n";
+  Rec.dump();
+
+  errs() << "Defs:\n";
+  for (RecordVector::const_iterator r = DefPrototypes.begin(),
+         rend = DefPrototypes.end();
+       r != rend;
+       ++r) {
+    (*r)->dump();
+  }
+}
+
+
+void RecordKeeper::dump() const { errs() << *this; }
+
+raw_ostream &llvm::operator<<(raw_ostream &OS, const RecordKeeper &RK) {
+  OS << "------------- Classes -----------------\n";
+  const std::map<std::string, Record*> &Classes = RK.getClasses();
+  for (std::map<std::string, Record*>::const_iterator I = Classes.begin(),
+         E = Classes.end(); I != E; ++I)
+    OS << "class " << *I->second;
+
+  OS << "------------- Defs -----------------\n";
+  const std::map<std::string, Record*> &Defs = RK.getDefs();
+  for (std::map<std::string, Record*>::const_iterator I = Defs.begin(),
+         E = Defs.end(); I != E; ++I)
+    OS << "def " << *I->second;
+  return OS;
+}
+
+
+/// getAllDerivedDefinitions - This method returns all concrete definitions
+/// that derive from the specified class name.  If a class with the specified
+/// name does not exist, an error is printed and true is returned.
+std::vector<Record*>
+RecordKeeper::getAllDerivedDefinitions(const std::string &ClassName) const {
+  Record *Class = Records.getClass(ClassName);
+  if (!Class)
+    throw "ERROR: Couldn't find the `" + ClassName + "' class!\n";
+
+  std::vector<Record*> Defs;
+  for (std::map<std::string, Record*>::const_iterator I = getDefs().begin(),
+         E = getDefs().end(); I != E; ++I)
+    if (I->second->isSubClassOf(Class))
+      Defs.push_back(I->second);
+
+  return Defs;
+}
+
diff --git a/src/LLVM/utils/TableGen/Record.h b/src/LLVM/utils/TableGen/Record.h
new file mode 100644
index 0000000..8f9fd95
--- /dev/null
+++ b/src/LLVM/utils/TableGen/Record.h
@@ -0,0 +1,1497 @@
+//===- Record.h - Classes to represent Table Records ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the main TableGen data structures, including the TableGen
+// types, values, and high-level data structures.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef RECORD_H
+#define RECORD_H
+
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/System/DataTypes.h"
+#include "llvm/Support/raw_ostream.h"
+#include <map>
+
+namespace llvm {
+class raw_ostream;
+
+// RecTy subclasses.
+class BitRecTy;
+class BitsRecTy;
+class IntRecTy;
+class StringRecTy;
+class ListRecTy;
+class CodeRecTy;
+class DagRecTy;
+class RecordRecTy;
+
+// Init subclasses.
+struct Init;
+class UnsetInit;
+class BitInit;
+class BitsInit;
+class IntInit;
+class StringInit;
+class CodeInit;
+class ListInit;
+class UnOpInit;
+class BinOpInit;
+class TernOpInit;
+class DefInit;
+class DagInit;
+class TypedInit;
+class VarInit;
+class FieldInit;
+class VarBitInit;
+class VarListElementInit;
+
+// Other classes.
+class Record;
+class RecordVal;
+struct MultiClass;
+
+//===----------------------------------------------------------------------===//
+//  Type Classes
+//===----------------------------------------------------------------------===//
+
+struct RecTy {
+  virtual ~RecTy() {}
+
+  virtual std::string getAsString() const = 0;
+  void print(raw_ostream &OS) const { OS << getAsString(); }
+  void dump() const;
+
+  /// typeIsConvertibleTo - Return true if all values of 'this' type can be
+  /// converted to the specified type.
+  virtual bool typeIsConvertibleTo(const RecTy *RHS) const = 0;
+
+public:   // These methods should only be called from subclasses of Init
+  virtual Init *convertValue( UnsetInit *UI) { return 0; }
+  virtual Init *convertValue(   BitInit *BI) { return 0; }
+  virtual Init *convertValue(  BitsInit *BI) { return 0; }
+  virtual Init *convertValue(   IntInit *II) { return 0; }
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue( UnOpInit *UI) {
+    return convertValue((TypedInit*)UI);
+  }
+  virtual Init *convertValue( BinOpInit *UI) {
+    return convertValue((TypedInit*)UI);
+  }
+  virtual Init *convertValue( TernOpInit *UI) {
+    return convertValue((TypedInit*)UI);
+  }
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( TypedInit *TI) { return 0; }
+  virtual Init *convertValue(   VarInit *VI) {
+    return convertValue((TypedInit*)VI);
+  }
+  virtual Init *convertValue( FieldInit *FI) {
+    return convertValue((TypedInit*)FI);
+  }
+
+public:   // These methods should only be called by subclasses of RecTy.
+  // baseClassOf - These virtual methods should be overloaded to return true iff
+  // all values of type 'RHS' can be converted to the 'this' type.
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) {
+  Ty.print(OS);
+  return OS;
+}
+
+
+/// BitRecTy - 'bit' - Represent a single bit
+///
+class BitRecTy : public RecTy {
+public:
+  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+  virtual Init *convertValue(   BitInit *BI) { return (Init*)BI; }
+  virtual Init *convertValue(  BitsInit *BI);
+  virtual Init *convertValue(   IntInit *II);
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
+  virtual Init *convertValue(VarBitInit *VB) { return (Init*)VB; }
+  virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( TypedInit *TI);
+  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
+  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
+
+  std::string getAsString() const { return "bit"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return true; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const;
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return true; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
+
+};
+
+
+// BitsRecTy - 'bits<n>' - Represent a fixed number of bits
+/// BitsRecTy - 'bits&lt;n&gt;' - Represent a fixed number of bits
+///
+class BitsRecTy : public RecTy {
+  unsigned Size;
+public:
+  explicit BitsRecTy(unsigned Sz) : Size(Sz) {}
+
+  unsigned getNumBits() const { return Size; }
+
+  virtual Init *convertValue( UnsetInit *UI);
+  virtual Init *convertValue(   BitInit *UI);
+  virtual Init *convertValue(  BitsInit *BI);
+  virtual Init *convertValue(   IntInit *II);
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( TypedInit *TI);
+  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
+  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
+
+  std::string getAsString() const;
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return Size == 1; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const {
+    return RHS->Size == Size;
+  }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return true; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
+
+};
+
+
+/// IntRecTy - 'int' - Represent an integer value of no particular size
+///
+class IntRecTy : public RecTy {
+public:
+  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+  virtual Init *convertValue(   BitInit *BI);
+  virtual Init *convertValue(  BitsInit *BI);
+  virtual Init *convertValue(   IntInit *II) { return (Init*)II; }
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( TypedInit *TI);
+  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
+  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
+
+  std::string getAsString() const { return "int"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return true; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const { return true; }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return true; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
+
+};
+
+/// StringRecTy - 'string' - Represent an string value
+///
+class StringRecTy : public RecTy {
+public:
+  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+  virtual Init *convertValue(   BitInit *BI) { return 0; }
+  virtual Init *convertValue(  BitsInit *BI) { return 0; }
+  virtual Init *convertValue(   IntInit *II) { return 0; }
+  virtual Init *convertValue(StringInit *SI) { return (Init*)SI; }
+  virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue( UnOpInit *BO);
+  virtual Init *convertValue( BinOpInit *BO);
+  virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
+
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( TypedInit *TI);
+  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
+  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
+
+  std::string getAsString() const { return "string"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return true; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
+};
+
+// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must be of
+// the specified type.
+/// ListRecTy - 'list&lt;Ty&gt;' - Represent a list of values, all of which must
+/// be of the specified type.
+///
+class ListRecTy : public RecTy {
+  RecTy *Ty;
+public:
+  explicit ListRecTy(RecTy *T) : Ty(T) {}
+
+  RecTy *getElementType() const { return Ty; }
+
+  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+  virtual Init *convertValue(   BitInit *BI) { return 0; }
+  virtual Init *convertValue(  BitsInit *BI) { return 0; }
+  virtual Init *convertValue(   IntInit *II) { return 0; }
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI);
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( TypedInit *TI);
+  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
+  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
+
+  std::string getAsString() const;
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const {
+    return RHS->getElementType()->typeIsConvertibleTo(Ty);
+  }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
+};
+
+/// CodeRecTy - 'code' - Represent an code fragment, function or method.
+///
+class CodeRecTy : public RecTy {
+public:
+  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+  virtual Init *convertValue(   BitInit *BI) { return 0; }
+  virtual Init *convertValue(  BitsInit *BI) { return 0; }
+  virtual Init *convertValue(   IntInit *II) { return 0; }
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue(  CodeInit *CI) { return (Init*)CI; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( TypedInit *TI);
+  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
+  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
+
+  std::string getAsString() const { return "code"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return true; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
+};
+
+/// DagRecTy - 'dag' - Represent a dag fragment
+///
+class DagRecTy : public RecTy {
+public:
+  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+  virtual Init *convertValue(   BitInit *BI) { return 0; }
+  virtual Init *convertValue(  BitsInit *BI) { return 0; }
+  virtual Init *convertValue(   IntInit *II) { return 0; }
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue( UnOpInit *BO);
+  virtual Init *convertValue( BinOpInit *BO);
+  virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
+  virtual Init *convertValue(   DagInit *CI) { return (Init*)CI; }
+  virtual Init *convertValue( TypedInit *TI);
+  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
+  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
+
+  std::string getAsString() const { return "dag"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return true; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
+};
+
+
+/// RecordRecTy - '[classname]' - Represent an instance of a class, such as:
+/// (R32 X = EAX).
+///
+class RecordRecTy : public RecTy {
+  Record *Rec;
+public:
+  explicit RecordRecTy(Record *R) : Rec(R) {}
+
+  Record *getRecord() const { return Rec; }
+
+  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+  virtual Init *convertValue(   BitInit *BI) { return 0; }
+  virtual Init *convertValue(  BitsInit *BI) { return 0; }
+  virtual Init *convertValue(   IntInit *II) { return 0; }
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue(   DefInit *DI);
+  virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( TypedInit *VI);
+  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
+  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
+
+  std::string getAsString() const;
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const;
+};
+
+/// resolveTypes - Find a common type that T1 and T2 convert to.
+/// Return 0 if no such type exists.
+///
+RecTy *resolveTypes(RecTy *T1, RecTy *T2);
+
+//===----------------------------------------------------------------------===//
+//  Initializer Classes
+//===----------------------------------------------------------------------===//
+
+struct Init {
+  virtual ~Init() {}
+
+  /// isComplete - This virtual method should be overridden by values that may
+  /// not be completely specified yet.
+  virtual bool isComplete() const { return true; }
+
+  /// print - Print out this value.
+  void print(raw_ostream &OS) const { OS << getAsString(); }
+
+  /// getAsString - Convert this value to a string form.
+  virtual std::string getAsString() const = 0;
+
+  /// dump - Debugging method that may be called through a debugger, just
+  /// invokes print on stderr.
+  void dump() const;
+
+  /// convertInitializerTo - This virtual function is a simple call-back
+  /// function that should be overridden to call the appropriate
+  /// RecTy::convertValue method.
+  ///
+  virtual Init *convertInitializerTo(RecTy *Ty) = 0;
+
+  /// convertInitializerBitRange - This method is used to implement the bitrange
+  /// selection operator.  Given an initializer, it selects the specified bits
+  /// out, returning them as a new init of bits type.  If it is not legal to use
+  /// the bit subscript operator on this initializer, return null.
+  ///
+  virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits) {
+    return 0;
+  }
+
+  /// convertInitListSlice - This method is used to implement the list slice
+  /// selection operator.  Given an initializer, it selects the specified list
+  /// elements, returning them as a new init of list type.  If it is not legal
+  /// to take a slice of this, return null.
+  ///
+  virtual Init *convertInitListSlice(const std::vector<unsigned> &Elements) {
+    return 0;
+  }
+
+  /// getFieldType - This method is used to implement the FieldInit class.
+  /// Implementors of this method should return the type of the named field if
+  /// they are of record type.
+  ///
+  virtual RecTy *getFieldType(const std::string &FieldName) const { return 0; }
+
+  /// getFieldInit - This method complements getFieldType to return the
+  /// initializer for the specified field.  If getFieldType returns non-null
+  /// this method should return non-null, otherwise it returns null.
+  ///
+  virtual Init *getFieldInit(Record &R, const RecordVal *RV,
+                             const std::string &FieldName) const {
+    return 0;
+  }
+
+  /// resolveReferences - This method is used by classes that refer to other
+  /// variables which may not be defined at the time the expression is formed.
+  /// If a value is set for the variable later, this method will be called on
+  /// users of the value to allow the value to propagate out.
+  ///
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV) {
+    return this;
+  }
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const Init &I) {
+  I.print(OS); return OS;
+}
+
+/// TypedInit - This is the common super-class of types that have a specific,
+/// explicit, type.
+///
+class TypedInit : public Init {
+  RecTy *Ty;
+public:
+  explicit TypedInit(RecTy *T) : Ty(T) {}
+
+  RecTy *getType() const { return Ty; }
+
+  virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
+  virtual Init *convertInitListSlice(const std::vector<unsigned> &Elements);
+
+  /// resolveBitReference - This method is used to implement
+  /// VarBitInit::resolveReferences.  If the bit is able to be resolved, we
+  /// simply return the resolved value, otherwise we return null.
+  ///
+  virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+                                    unsigned Bit) = 0;
+
+  /// resolveListElementReference - This method is used to implement
+  /// VarListElementInit::resolveReferences.  If the list element is resolvable
+  /// now, we return the resolved value, otherwise we return null.
+  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                            unsigned Elt) = 0;
+};
+
+
+/// UnsetInit - ? - Represents an uninitialized value
+///
+class UnsetInit : public Init {
+public:
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+
+  virtual bool isComplete() const { return false; }
+  virtual std::string getAsString() const { return "?"; }
+};
+
+
+/// BitInit - true/false - Represent a concrete initializer for a bit.
+///
+class BitInit : public Init {
+  bool Value;
+public:
+  explicit BitInit(bool V) : Value(V) {}
+
+  bool getValue() const { return Value; }
+
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+
+  virtual std::string getAsString() const { return Value ? "1" : "0"; }
+};
+
+/// BitsInit - { a, b, c } - Represents an initializer for a BitsRecTy value.
+/// It contains a vector of bits, whose size is determined by the type.
+///
+class BitsInit : public Init {
+  std::vector<Init*> Bits;
+public:
+  explicit BitsInit(unsigned Size) : Bits(Size) {}
+
+  unsigned getNumBits() const { return Bits.size(); }
+
+  Init *getBit(unsigned Bit) const {
+    assert(Bit < Bits.size() && "Bit index out of range!");
+    return Bits[Bit];
+  }
+  void setBit(unsigned Bit, Init *V) {
+    assert(Bit < Bits.size() && "Bit index out of range!");
+    assert(Bits[Bit] == 0 && "Bit already set!");
+    Bits[Bit] = V;
+  }
+
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+  virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
+
+  virtual bool isComplete() const {
+    for (unsigned i = 0; i != getNumBits(); ++i)
+      if (!getBit(i)->isComplete()) return false;
+    return true;
+  }
+  bool allInComplete() const {
+    for (unsigned i = 0; i != getNumBits(); ++i)
+      if (getBit(i)->isComplete()) return false;
+    return true;
+  }
+  virtual std::string getAsString() const;
+
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+};
+
+
+/// IntInit - 7 - Represent an initalization by a literal integer value.
+///
+class IntInit : public TypedInit {
+  int64_t Value;
+public:
+  explicit IntInit(int64_t V) : TypedInit(new IntRecTy), Value(V) {}
+
+  int64_t getValue() const { return Value; }
+
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+  virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
+
+  virtual std::string getAsString() const;
+
+  /// resolveBitReference - This method is used to implement
+  /// VarBitInit::resolveReferences.  If the bit is able to be resolved, we
+  /// simply return the resolved value, otherwise we return null.
+  ///
+  virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+                                    unsigned Bit) {
+    assert(0 && "Illegal bit reference off int");
+    return 0;
+  }
+
+  /// resolveListElementReference - This method is used to implement
+  /// VarListElementInit::resolveReferences.  If the list element is resolvable
+  /// now, we return the resolved value, otherwise we return null.
+  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                            unsigned Elt) {
+    assert(0 && "Illegal element reference off int");
+    return 0;
+  }
+};
+
+
+/// StringInit - "foo" - Represent an initialization by a string value.
+///
+class StringInit : public TypedInit {
+  std::string Value;
+public:
+  explicit StringInit(const std::string &V)
+    : TypedInit(new StringRecTy), Value(V) {}
+
+  const std::string &getValue() const { return Value; }
+
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+
+  virtual std::string getAsString() const { return "\"" + Value + "\""; }
+
+  /// resolveBitReference - This method is used to implement
+  /// VarBitInit::resolveReferences.  If the bit is able to be resolved, we
+  /// simply return the resolved value, otherwise we return null.
+  ///
+  virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+                                    unsigned Bit) {
+    assert(0 && "Illegal bit reference off string");
+    return 0;
+  }
+
+  /// resolveListElementReference - This method is used to implement
+  /// VarListElementInit::resolveReferences.  If the list element is resolvable
+  /// now, we return the resolved value, otherwise we return null.
+  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                            unsigned Elt) {
+    assert(0 && "Illegal element reference off string");
+    return 0;
+  }
+};
+
+/// CodeInit - "[{...}]" - Represent a code fragment.
+///
+class CodeInit : public Init {
+  std::string Value;
+public:
+  explicit CodeInit(const std::string &V) : Value(V) {}
+
+  const std::string getValue() const { return Value; }
+
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+
+  virtual std::string getAsString() const { return "[{" + Value + "}]"; }
+};
+
+/// ListInit - [AL, AH, CL] - Represent a list of defs
+///
+class ListInit : public TypedInit {
+  std::vector<Init*> Values;
+public:
+  typedef std::vector<Init*>::iterator       iterator;
+  typedef std::vector<Init*>::const_iterator const_iterator;
+
+  explicit ListInit(std::vector<Init*> &Vs, RecTy *EltTy)
+    : TypedInit(new ListRecTy(EltTy)) {
+    Values.swap(Vs);
+  }
+  explicit ListInit(iterator Start, iterator End, RecTy *EltTy)
+      : TypedInit(new ListRecTy(EltTy)), Values(Start, End) {}
+
+  unsigned getSize() const { return Values.size(); }
+  Init *getElement(unsigned i) const {
+    assert(i < Values.size() && "List element index out of range!");
+    return Values[i];
+  }
+
+  Record *getElementAsRecord(unsigned i) const;
+
+  Init *convertInitListSlice(const std::vector<unsigned> &Elements);
+
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+
+  /// resolveReferences - This method is used by classes that refer to other
+  /// variables which may not be defined at the time they expression is formed.
+  /// If a value is set for the variable later, this method will be called on
+  /// users of the value to allow the value to propagate out.
+  ///
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+
+  virtual std::string getAsString() const;
+
+  inline iterator       begin()       { return Values.begin(); }
+  inline const_iterator begin() const { return Values.begin(); }
+  inline iterator       end  ()       { return Values.end();   }
+  inline const_iterator end  () const { return Values.end();   }
+
+  inline size_t         size () const { return Values.size();  }
+  inline bool           empty() const { return Values.empty(); }
+
+  /// resolveBitReference - This method is used to implement
+  /// VarBitInit::resolveReferences.  If the bit is able to be resolved, we
+  /// simply return the resolved value, otherwise we return null.
+  ///
+  virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+                                    unsigned Bit) {
+    assert(0 && "Illegal bit reference off list");
+    return 0;
+  }
+
+  /// resolveListElementReference - This method is used to implement
+  /// VarListElementInit::resolveReferences.  If the list element is resolvable
+  /// now, we return the resolved value, otherwise we return null.
+  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                            unsigned Elt);
+};
+
+
+/// OpInit - Base class for operators
+///
+class OpInit : public TypedInit {
+public:
+  OpInit(RecTy *Type) : TypedInit(Type) {}
+
+  // Clone - Clone this operator, replacing arguments with the new list
+  virtual OpInit *clone(std::vector<Init *> &Operands) = 0;
+
+  virtual int getNumOperands() const = 0;
+  virtual Init *getOperand(int i) = 0;
+
+  // Fold - If possible, fold this to a simpler init.  Return this if not
+  // possible to fold.
+  virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) = 0;
+
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+
+  virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+                                    unsigned Bit);
+  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                            unsigned Elt);
+};
+
+
+/// UnOpInit - !op (X) - Transform an init.
+///
+class UnOpInit : public OpInit {
+public:
+  enum UnaryOp { CAST, CAR, CDR, LNULL };
+private:
+  UnaryOp Opc;
+  Init *LHS;
+public:
+  UnOpInit(UnaryOp opc, Init *lhs, RecTy *Type) :
+      OpInit(Type), Opc(opc), LHS(lhs) {
+  }
+
+  // Clone - Clone this operator, replacing arguments with the new list
+  virtual OpInit *clone(std::vector<Init *> &Operands) {
+    assert(Operands.size() == 1 &&
+           "Wrong number of operands for unary operation");
+    return new UnOpInit(getOpcode(), *Operands.begin(), getType());
+  }
+
+  int getNumOperands() const { return 1; }
+  Init *getOperand(int i) {
+    assert(i == 0 && "Invalid operand id for unary operator");
+    return getOperand();
+  }
+
+  UnaryOp getOpcode() const { return Opc; }
+  Init *getOperand() const { return LHS; }
+
+  // Fold - If possible, fold this to a simpler init.  Return this if not
+  // possible to fold.
+  Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
+
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+
+  /// getFieldType - This method is used to implement the FieldInit class.
+  /// Implementors of this method should return the type of the named field if
+  /// they are of record type.
+  ///
+  virtual RecTy *getFieldType(const std::string &FieldName) const;
+
+  virtual std::string getAsString() const;
+};
+
+/// BinOpInit - !op (X, Y) - Combine two inits.
+///
+class BinOpInit : public OpInit {
+public:
+  enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, NAMECONCAT, EQ };
+private:
+  BinaryOp Opc;
+  Init *LHS, *RHS;
+public:
+  BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) :
+      OpInit(Type), Opc(opc), LHS(lhs), RHS(rhs) {
+  }
+
+  // Clone - Clone this operator, replacing arguments with the new list
+  virtual OpInit *clone(std::vector<Init *> &Operands) {
+    assert(Operands.size() == 2 &&
+           "Wrong number of operands for binary operation");
+    return new BinOpInit(getOpcode(), Operands[0], Operands[1], getType());
+  }
+
+  int getNumOperands() const { return 2; }
+  Init *getOperand(int i) {
+    assert((i == 0 || i == 1) && "Invalid operand id for binary operator");
+    if (i == 0) {
+      return getLHS();
+    } else {
+      return getRHS();
+    }
+  }
+
+  BinaryOp getOpcode() const { return Opc; }
+  Init *getLHS() const { return LHS; }
+  Init *getRHS() const { return RHS; }
+
+  // Fold - If possible, fold this to a simpler init.  Return this if not
+  // possible to fold.
+  Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
+
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+
+  virtual std::string getAsString() const;
+};
+
+/// TernOpInit - !op (X, Y, Z) - Combine two inits.
+///
+class TernOpInit : public OpInit {
+public:
+  enum TernaryOp { SUBST, FOREACH, IF };
+private:
+  TernaryOp Opc;
+  Init *LHS, *MHS, *RHS;
+public:
+  TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, RecTy *Type) :
+      OpInit(Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {
+  }
+
+  // Clone - Clone this operator, replacing arguments with the new list
+  virtual OpInit *clone(std::vector<Init *> &Operands) {
+    assert(Operands.size() == 3 &&
+           "Wrong number of operands for ternary operation");
+    return new TernOpInit(getOpcode(), Operands[0], Operands[1], Operands[2],
+                          getType());
+  }
+
+  int getNumOperands() const { return 3; }
+  Init *getOperand(int i) {
+    assert((i == 0 || i == 1 || i == 2) &&
+           "Invalid operand id for ternary operator");
+    if (i == 0) {
+      return getLHS();
+    } else if (i == 1) {
+      return getMHS();
+    } else {
+      return getRHS();
+    }
+  }
+
+  TernaryOp getOpcode() const { return Opc; }
+  Init *getLHS() const { return LHS; }
+  Init *getMHS() const { return MHS; }
+  Init *getRHS() const { return RHS; }
+
+  // Fold - If possible, fold this to a simpler init.  Return this if not
+  // possible to fold.
+  Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
+
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+
+  virtual std::string getAsString() const;
+};
+
+
+/// VarInit - 'Opcode' - Represent a reference to an entire variable object.
+///
+class VarInit : public TypedInit {
+  std::string VarName;
+public:
+  explicit VarInit(const std::string &VN, RecTy *T)
+    : TypedInit(T), VarName(VN) {}
+
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+
+  const std::string &getName() const { return VarName; }
+
+  virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+                                    unsigned Bit);
+  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                            unsigned Elt);
+
+  virtual RecTy *getFieldType(const std::string &FieldName) const;
+  virtual Init *getFieldInit(Record &R, const RecordVal *RV,
+                             const std::string &FieldName) const;
+
+  /// resolveReferences - This method is used by classes that refer to other
+  /// variables which may not be defined at the time they expression is formed.
+  /// If a value is set for the variable later, this method will be called on
+  /// users of the value to allow the value to propagate out.
+  ///
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+
+  virtual std::string getAsString() const { return VarName; }
+};
+
+
+/// VarBitInit - Opcode{0} - Represent access to one bit of a variable or field.
+///
+class VarBitInit : public Init {
+  TypedInit *TI;
+  unsigned Bit;
+public:
+  VarBitInit(TypedInit *T, unsigned B) : TI(T), Bit(B) {
+    assert(T->getType() && dynamic_cast<BitsRecTy*>(T->getType()) &&
+           ((BitsRecTy*)T->getType())->getNumBits() > B &&
+           "Illegal VarBitInit expression!");
+  }
+
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+
+  TypedInit *getVariable() const { return TI; }
+  unsigned getBitNum() const { return Bit; }
+
+  virtual std::string getAsString() const;
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+};
+
+/// VarListElementInit - List[4] - Represent access to one element of a var or
+/// field.
+class VarListElementInit : public TypedInit {
+  TypedInit *TI;
+  unsigned Element;
+public:
+  VarListElementInit(TypedInit *T, unsigned E)
+    : TypedInit(dynamic_cast<ListRecTy*>(T->getType())->getElementType()),
+                TI(T), Element(E) {
+    assert(T->getType() && dynamic_cast<ListRecTy*>(T->getType()) &&
+           "Illegal VarBitInit expression!");
+  }
+
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+
+  TypedInit *getVariable() const { return TI; }
+  unsigned getElementNum() const { return Element; }
+
+  virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+                                    unsigned Bit);
+
+  /// resolveListElementReference - This method is used to implement
+  /// VarListElementInit::resolveReferences.  If the list element is resolvable
+  /// now, we return the resolved value, otherwise we return null.
+  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                            unsigned Elt);
+
+  virtual std::string getAsString() const;
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+};
+
+/// DefInit - AL - Represent a reference to a 'def' in the description
+///
+class DefInit : public TypedInit {
+  Record *Def;
+public:
+  explicit DefInit(Record *D) : TypedInit(new RecordRecTy(D)), Def(D) {}
+
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+
+  Record *getDef() const { return Def; }
+
+  //virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
+
+  virtual RecTy *getFieldType(const std::string &FieldName) const;
+  virtual Init *getFieldInit(Record &R, const RecordVal *RV,
+                             const std::string &FieldName) const;
+
+  virtual std::string getAsString() const;
+
+  /// resolveBitReference - This method is used to implement
+  /// VarBitInit::resolveReferences.  If the bit is able to be resolved, we
+  /// simply return the resolved value, otherwise we return null.
+  ///
+  virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+                                    unsigned Bit) {
+    assert(0 && "Illegal bit reference off def");
+    return 0;
+  }
+
+  /// resolveListElementReference - This method is used to implement
+  /// VarListElementInit::resolveReferences.  If the list element is resolvable
+  /// now, we return the resolved value, otherwise we return null.
+  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                            unsigned Elt) {
+    assert(0 && "Illegal element reference off def");
+    return 0;
+  }
+};
+
+
+/// FieldInit - X.Y - Represent a reference to a subfield of a variable
+///
+class FieldInit : public TypedInit {
+  Init *Rec;                // Record we are referring to
+  std::string FieldName;    // Field we are accessing
+public:
+  FieldInit(Init *R, const std::string &FN)
+    : TypedInit(R->getFieldType(FN)), Rec(R), FieldName(FN) {
+    assert(getType() && "FieldInit with non-record type!");
+  }
+
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+
+  virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+                                    unsigned Bit);
+  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                            unsigned Elt);
+
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+
+  virtual std::string getAsString() const {
+    return Rec->getAsString() + "." + FieldName;
+  }
+};
+
+/// DagInit - (v a, b) - Represent a DAG tree value.  DAG inits are required
+/// to have at least one value then a (possibly empty) list of arguments.  Each
+/// argument can have a name associated with it.
+///
+class DagInit : public TypedInit {
+  Init *Val;
+  std::string ValName;
+  std::vector<Init*> Args;
+  std::vector<std::string> ArgNames;
+public:
+  DagInit(Init *V, std::string VN,
+          const std::vector<std::pair<Init*, std::string> > &args)
+    : TypedInit(new DagRecTy), Val(V), ValName(VN) {
+    Args.reserve(args.size());
+    ArgNames.reserve(args.size());
+    for (unsigned i = 0, e = args.size(); i != e; ++i) {
+      Args.push_back(args[i].first);
+      ArgNames.push_back(args[i].second);
+    }
+  }
+  DagInit(Init *V, std::string VN, const std::vector<Init*> &args,
+          const std::vector<std::string> &argNames)
+    : TypedInit(new DagRecTy), Val(V), ValName(VN), Args(args),
+      ArgNames(argNames) { }
+
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+
+  Init *getOperator() const { return Val; }
+
+  const std::string &getName() const { return ValName; }
+
+  unsigned getNumArgs() const { return Args.size(); }
+  Init *getArg(unsigned Num) const {
+    assert(Num < Args.size() && "Arg number out of range!");
+    return Args[Num];
+  }
+  const std::string &getArgName(unsigned Num) const {
+    assert(Num < ArgNames.size() && "Arg number out of range!");
+    return ArgNames[Num];
+  }
+
+  void setArg(unsigned Num, Init *I) {
+    assert(Num < Args.size() && "Arg number out of range!");
+    Args[Num] = I;
+  }
+
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+
+  virtual std::string getAsString() const;
+
+  typedef std::vector<Init*>::iterator             arg_iterator;
+  typedef std::vector<Init*>::const_iterator       const_arg_iterator;
+  typedef std::vector<std::string>::iterator       name_iterator;
+  typedef std::vector<std::string>::const_iterator const_name_iterator;
+
+  inline arg_iterator        arg_begin()       { return Args.begin(); }
+  inline const_arg_iterator  arg_begin() const { return Args.begin(); }
+  inline arg_iterator        arg_end  ()       { return Args.end();   }
+  inline const_arg_iterator  arg_end  () const { return Args.end();   }
+
+  inline size_t              arg_size () const { return Args.size();  }
+  inline bool                arg_empty() const { return Args.empty(); }
+
+  inline name_iterator       name_begin()       { return ArgNames.begin(); }
+  inline const_name_iterator name_begin() const { return ArgNames.begin(); }
+  inline name_iterator       name_end  ()       { return ArgNames.end();   }
+  inline const_name_iterator name_end  () const { return ArgNames.end();   }
+
+  inline size_t              name_size () const { return ArgNames.size();  }
+  inline bool                name_empty() const { return ArgNames.empty(); }
+
+  virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+                                    unsigned Bit) {
+    assert(0 && "Illegal bit reference off dag");
+    return 0;
+  }
+
+  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                            unsigned Elt) {
+    assert(0 && "Illegal element reference off dag");
+    return 0;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//  High-Level Classes
+//===----------------------------------------------------------------------===//
+
+class RecordVal {
+  std::string Name;
+  RecTy *Ty;
+  unsigned Prefix;
+  Init *Value;
+public:
+  RecordVal(const std::string &N, RecTy *T, unsigned P);
+
+  const std::string &getName() const { return Name; }
+
+  unsigned getPrefix() const { return Prefix; }
+  RecTy *getType() const { return Ty; }
+  Init *getValue() const { return Value; }
+
+  bool setValue(Init *V) {
+    if (V) {
+      Value = V->convertInitializerTo(Ty);
+      return Value == 0;
+    }
+    Value = 0;
+    return false;
+  }
+
+  void dump() const;
+  void print(raw_ostream &OS, bool PrintSem = true) const;
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const RecordVal &RV) {
+  RV.print(OS << "  ");
+  return OS;
+}
+
+class Record {
+  static unsigned LastID;
+
+  // Unique record ID.
+  unsigned ID;
+  std::string Name;
+  SMLoc Loc;
+  std::vector<std::string> TemplateArgs;
+  std::vector<RecordVal> Values;
+  std::vector<Record*> SuperClasses;
+public:
+
+  explicit Record(const std::string &N, SMLoc loc) :
+    ID(LastID++), Name(N), Loc(loc) {}
+  ~Record() {}
+
+  
+  static unsigned getNewUID() { return LastID++; }
+    
+    
+  unsigned getID() const { return ID; }
+
+  const std::string &getName() const { return Name; }
+  void setName(const std::string &Name);  // Also updates RecordKeeper.
+
+  SMLoc getLoc() const { return Loc; }
+
+  const std::vector<std::string> &getTemplateArgs() const {
+    return TemplateArgs;
+  }
+  const std::vector<RecordVal> &getValues() const { return Values; }
+  const std::vector<Record*>   &getSuperClasses() const { return SuperClasses; }
+
+  bool isTemplateArg(StringRef Name) const {
+    for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i)
+      if (TemplateArgs[i] == Name) return true;
+    return false;
+  }
+
+  const RecordVal *getValue(StringRef Name) const {
+    for (unsigned i = 0, e = Values.size(); i != e; ++i)
+      if (Values[i].getName() == Name) return &Values[i];
+    return 0;
+  }
+  RecordVal *getValue(StringRef Name) {
+    for (unsigned i = 0, e = Values.size(); i != e; ++i)
+      if (Values[i].getName() == Name) return &Values[i];
+    return 0;
+  }
+
+  void addTemplateArg(StringRef Name) {
+    assert(!isTemplateArg(Name) && "Template arg already defined!");
+    TemplateArgs.push_back(Name);
+  }
+
+  void addValue(const RecordVal &RV) {
+    assert(getValue(RV.getName()) == 0 && "Value already added!");
+    Values.push_back(RV);
+  }
+
+  void removeValue(StringRef Name) {
+    for (unsigned i = 0, e = Values.size(); i != e; ++i)
+      if (Values[i].getName() == Name) {
+        Values.erase(Values.begin()+i);
+        return;
+      }
+    assert(0 && "Cannot remove an entry that does not exist!");
+  }
+
+  bool isSubClassOf(const Record *R) const {
+    for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
+      if (SuperClasses[i] == R)
+        return true;
+    return false;
+  }
+
+  bool isSubClassOf(StringRef Name) const {
+    for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
+      if (SuperClasses[i]->getName() == Name)
+        return true;
+    return false;
+  }
+
+  void addSuperClass(Record *R) {
+    assert(!isSubClassOf(R) && "Already subclassing record!");
+    SuperClasses.push_back(R);
+  }
+
+  /// resolveReferences - If there are any field references that refer to fields
+  /// that have been filled in, we can propagate the values now.
+  ///
+  void resolveReferences() { resolveReferencesTo(0); }
+
+  /// resolveReferencesTo - If anything in this record refers to RV, replace the
+  /// reference to RV with the RHS of RV.  If RV is null, we resolve all
+  /// possible references.
+  void resolveReferencesTo(const RecordVal *RV);
+
+  void dump() const;
+
+  //===--------------------------------------------------------------------===//
+  // High-level methods useful to tablegen back-ends
+  //
+
+  /// getValueInit - Return the initializer for a value with the specified name,
+  /// or throw an exception if the field does not exist.
+  ///
+  Init *getValueInit(StringRef FieldName) const;
+
+  /// getValueAsString - This method looks up the specified field and returns
+  /// its value as a string, throwing an exception if the field does not exist
+  /// or if the value is not a string.
+  ///
+  std::string getValueAsString(StringRef FieldName) const;
+
+  /// getValueAsBitsInit - This method looks up the specified field and returns
+  /// its value as a BitsInit, throwing an exception if the field does not exist
+  /// or if the value is not the right type.
+  ///
+  BitsInit *getValueAsBitsInit(StringRef FieldName) const;
+
+  /// getValueAsListInit - This method looks up the specified field and returns
+  /// its value as a ListInit, throwing an exception if the field does not exist
+  /// or if the value is not the right type.
+  ///
+  ListInit *getValueAsListInit(StringRef FieldName) const;
+
+  /// getValueAsListOfDefs - This method looks up the specified field and
+  /// returns its value as a vector of records, throwing an exception if the
+  /// field does not exist or if the value is not the right type.
+  ///
+  std::vector<Record*> getValueAsListOfDefs(StringRef FieldName) const;
+
+  /// getValueAsListOfInts - This method looks up the specified field and returns
+  /// its value as a vector of integers, throwing an exception if the field does
+  /// not exist or if the value is not the right type.
+  ///
+  std::vector<int64_t> getValueAsListOfInts(StringRef FieldName) const;
+
+  /// getValueAsDef - This method looks up the specified field and returns its
+  /// value as a Record, throwing an exception if the field does not exist or if
+  /// the value is not the right type.
+  ///
+  Record *getValueAsDef(StringRef FieldName) const;
+
+  /// getValueAsBit - This method looks up the specified field and returns its
+  /// value as a bit, throwing an exception if the field does not exist or if
+  /// the value is not the right type.
+  ///
+  bool getValueAsBit(StringRef FieldName) const;
+
+  /// getValueAsInt - This method looks up the specified field and returns its
+  /// value as an int64_t, throwing an exception if the field does not exist or
+  /// if the value is not the right type.
+  ///
+  int64_t getValueAsInt(StringRef FieldName) const;
+
+  /// getValueAsDag - This method looks up the specified field and returns its
+  /// value as an Dag, throwing an exception if the field does not exist or if
+  /// the value is not the right type.
+  ///
+  DagInit *getValueAsDag(StringRef FieldName) const;
+
+  /// getValueAsCode - This method looks up the specified field and returns
+  /// its value as the string data in a CodeInit, throwing an exception if the
+  /// field does not exist or if the value is not a code object.
+  ///
+  std::string getValueAsCode(StringRef FieldName) const;
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const Record &R);
+
+struct MultiClass {
+  Record Rec;  // Placeholder for template args and Name.
+  typedef std::vector<Record*> RecordVector;
+  RecordVector DefPrototypes;
+
+  void dump() const;
+
+  MultiClass(const std::string &Name, SMLoc Loc) : Rec(Name, Loc) {}
+};
+
+class RecordKeeper {
+  std::map<std::string, Record*> Classes, Defs;
+public:
+  ~RecordKeeper() {
+    for (std::map<std::string, Record*>::iterator I = Classes.begin(),
+           E = Classes.end(); I != E; ++I)
+      delete I->second;
+    for (std::map<std::string, Record*>::iterator I = Defs.begin(),
+           E = Defs.end(); I != E; ++I)
+      delete I->second;
+  }
+
+  const std::map<std::string, Record*> &getClasses() const { return Classes; }
+  const std::map<std::string, Record*> &getDefs() const { return Defs; }
+
+  Record *getClass(const std::string &Name) const {
+    std::map<std::string, Record*>::const_iterator I = Classes.find(Name);
+    return I == Classes.end() ? 0 : I->second;
+  }
+  Record *getDef(const std::string &Name) const {
+    std::map<std::string, Record*>::const_iterator I = Defs.find(Name);
+    return I == Defs.end() ? 0 : I->second;
+  }
+  void addClass(Record *R) {
+    assert(getClass(R->getName()) == 0 && "Class already exists!");
+    Classes.insert(std::make_pair(R->getName(), R));
+  }
+  void addDef(Record *R) {
+    assert(getDef(R->getName()) == 0 && "Def already exists!");
+    Defs.insert(std::make_pair(R->getName(), R));
+  }
+
+  /// removeClass - Remove, but do not delete, the specified record.
+  ///
+  void removeClass(const std::string &Name) {
+    assert(Classes.count(Name) && "Class does not exist!");
+    Classes.erase(Name);
+  }
+  /// removeDef - Remove, but do not delete, the specified record.
+  ///
+  void removeDef(const std::string &Name) {
+    assert(Defs.count(Name) && "Def does not exist!");
+    Defs.erase(Name);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // High-level helper methods, useful for tablegen backends...
+
+  /// getAllDerivedDefinitions - This method returns all concrete definitions
+  /// that derive from the specified class name.  If a class with the specified
+  /// name does not exist, an exception is thrown.
+  std::vector<Record*>
+  getAllDerivedDefinitions(const std::string &ClassName) const;
+
+
+  void dump() const;
+};
+
+/// LessRecord - Sorting predicate to sort record pointers by name.
+///
+struct LessRecord {
+  bool operator()(const Record *Rec1, const Record *Rec2) const {
+    return StringRef(Rec1->getName()).compare_numeric(Rec2->getName()) < 0;
+  }
+};
+
+/// LessRecordFieldName - Sorting predicate to sort record pointers by their
+/// name field.
+///
+struct LessRecordFieldName {
+  bool operator()(const Record *Rec1, const Record *Rec2) const {
+    return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name");
+  }
+};
+
+
+class TGError {
+  SMLoc Loc;
+  std::string Message;
+public:
+  TGError(SMLoc loc, const std::string &message) : Loc(loc), Message(message) {}
+
+  SMLoc getLoc() const { return Loc; }
+  const std::string &getMessage() const { return Message; }
+};
+
+
+raw_ostream &operator<<(raw_ostream &OS, const RecordKeeper &RK);
+
+extern RecordKeeper Records;
+
+void PrintError(SMLoc ErrorLoc, const std::string &Msg);
+
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/utils/TableGen/RegisterInfoEmitter.cpp b/src/LLVM/utils/TableGen/RegisterInfoEmitter.cpp
new file mode 100644
index 0000000..a3ca0bc
--- /dev/null
+++ b/src/LLVM/utils/TableGen/RegisterInfoEmitter.cpp
@@ -0,0 +1,1045 @@
+//===- RegisterInfoEmitter.cpp - Generate a Register File Desc. -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend is responsible for emitting a description of a target
+// register file for a code generator.  It uses instances of the Register,
+// RegisterAliases, and RegisterClass classes to gather this information.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RegisterInfoEmitter.h"
+#include "CodeGenTarget.h"
+#include "CodeGenRegisters.h"
+#include "Record.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/STLExtras.h"
+#include <algorithm>
+#include <set>
+using namespace llvm;
+
+// runEnums - Print out enum values for all of the registers.
+void RegisterInfoEmitter::runEnums(raw_ostream &OS) {
+  CodeGenTarget Target;
+  const std::vector<CodeGenRegister> &Registers = Target.getRegisters();
+
+  std::string Namespace = Registers[0].TheDef->getValueAsString("Namespace");
+
+  EmitSourceFileHeader("Target Register Enum Values", OS);
+  OS << "namespace llvm {\n\n";
+
+  if (!Namespace.empty())
+    OS << "namespace " << Namespace << " {\n";
+  OS << "enum {\n  NoRegister,\n";
+
+  for (unsigned i = 0, e = Registers.size(); i != e; ++i)
+    OS << "  " << Registers[i].getName() << ", \t// " << i+1 << "\n";
+  OS << "  NUM_TARGET_REGS \t// " << Registers.size()+1 << "\n";
+  OS << "};\n";
+  if (!Namespace.empty())
+    OS << "}\n";
+
+  const std::vector<Record*> SubRegIndices = Target.getSubRegIndices();
+  if (!SubRegIndices.empty()) {
+    OS << "\n// Subregister indices\n";
+    Namespace = SubRegIndices[0]->getValueAsString("Namespace");
+    if (!Namespace.empty())
+      OS << "namespace " << Namespace << " {\n";
+    OS << "enum {\n  NoSubRegister,\n";
+    for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i)
+      OS << "  " << SubRegIndices[i]->getName() << ",\t// " << i+1 << "\n";
+    OS << "  NUM_TARGET_SUBREGS = " << SubRegIndices.size()+1 << "\n";
+    OS << "};\n";
+    if (!Namespace.empty())
+      OS << "}\n";
+  }
+  OS << "} // End llvm namespace \n";
+}
+
+void RegisterInfoEmitter::runHeader(raw_ostream &OS) {
+  EmitSourceFileHeader("Register Information Header Fragment", OS);
+  CodeGenTarget Target;
+  const std::string &TargetName = Target.getName();
+  std::string ClassName = TargetName + "GenRegisterInfo";
+
+  OS << "#include \"llvm/Target/TargetRegisterInfo.h\"\n";
+  OS << "#include <string>\n\n";
+
+  OS << "namespace llvm {\n\n";
+
+  OS << "struct " << ClassName << " : public TargetRegisterInfo {\n"
+     << "  explicit " << ClassName
+     << "(int CallFrameSetupOpcode = -1, int CallFrameDestroyOpcode = -1);\n"
+     << "  virtual int getDwarfRegNumFull(unsigned RegNum, "
+     << "unsigned Flavour) const;\n"
+     << "  virtual int getDwarfRegNum(unsigned RegNum, bool isEH) const = 0;\n"
+     << "  virtual bool needsStackRealignment(const MachineFunction &) const\n"
+     << "     { return false; }\n"
+     << "  unsigned getSubReg(unsigned RegNo, unsigned Index) const;\n"
+     << "  unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const;\n"
+     << "  unsigned composeSubRegIndices(unsigned, unsigned) const;\n"
+     << "};\n\n";
+
+  const std::vector<CodeGenRegisterClass> &RegisterClasses =
+    Target.getRegisterClasses();
+
+  if (!RegisterClasses.empty()) {
+    OS << "namespace " << RegisterClasses[0].Namespace
+       << " { // Register classes\n";
+       
+    OS << "  enum {\n";
+    for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
+      if (i) OS << ",\n";
+      OS << "    " << RegisterClasses[i].getName() << "RegClassID";
+      OS << " = " << i;
+    }
+    OS << "\n  };\n\n";
+
+    for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
+      const std::string &Name = RegisterClasses[i].getName();
+
+      // Output the register class definition.
+      OS << "  struct " << Name << "Class : public TargetRegisterClass {\n"
+         << "    " << Name << "Class();\n"
+         << RegisterClasses[i].MethodProtos << "  };\n";
+
+      // Output the extern for the instance.
+      OS << "  extern " << Name << "Class\t" << Name << "RegClass;\n";
+      // Output the extern for the pointer to the instance (should remove).
+      OS << "  static TargetRegisterClass * const "<< Name <<"RegisterClass = &"
+         << Name << "RegClass;\n";
+    }
+    OS << "} // end of namespace " << TargetName << "\n\n";
+  }
+  OS << "} // End llvm namespace \n";
+}
+
+bool isSubRegisterClass(const CodeGenRegisterClass &RC,
+                        std::set<Record*> &RegSet) {
+  for (unsigned i = 0, e = RC.Elements.size(); i != e; ++i) {
+    Record *Reg = RC.Elements[i];
+    if (!RegSet.count(Reg))
+      return false;
+  }
+  return true;
+}
+
+static void addSuperReg(Record *R, Record *S,
+                  std::map<Record*, std::set<Record*>, LessRecord> &SubRegs,
+                  std::map<Record*, std::set<Record*>, LessRecord> &SuperRegs,
+                  std::map<Record*, std::set<Record*>, LessRecord> &Aliases) {
+  if (R == S) {
+    errs() << "Error: recursive sub-register relationship between"
+           << " register " << getQualifiedName(R)
+           << " and its sub-registers?\n";
+    abort();
+  }
+  if (!SuperRegs[R].insert(S).second)
+    return;
+  SubRegs[S].insert(R);
+  Aliases[R].insert(S);
+  Aliases[S].insert(R);
+  if (SuperRegs.count(S))
+    for (std::set<Record*>::iterator I = SuperRegs[S].begin(),
+           E = SuperRegs[S].end(); I != E; ++I)
+      addSuperReg(R, *I, SubRegs, SuperRegs, Aliases);
+}
+
+static void addSubSuperReg(Record *R, Record *S,
+                   std::map<Record*, std::set<Record*>, LessRecord> &SubRegs,
+                   std::map<Record*, std::set<Record*>, LessRecord> &SuperRegs,
+                   std::map<Record*, std::set<Record*>, LessRecord> &Aliases) {
+  if (R == S) {
+    errs() << "Error: recursive sub-register relationship between"
+           << " register " << getQualifiedName(R)
+           << " and its sub-registers?\n";
+    abort();
+  }
+
+  if (!SubRegs[R].insert(S).second)
+    return;
+  addSuperReg(S, R, SubRegs, SuperRegs, Aliases);
+  Aliases[R].insert(S);
+  Aliases[S].insert(R);
+  if (SubRegs.count(S))
+    for (std::set<Record*>::iterator I = SubRegs[S].begin(),
+           E = SubRegs[S].end(); I != E; ++I)
+      addSubSuperReg(R, *I, SubRegs, SuperRegs, Aliases);
+}
+
+struct RegisterMaps {
+  // Map SubRegIndex -> Register
+  typedef std::map<Record*, Record*, LessRecord> SubRegMap;
+  // Map Register -> SubRegMap
+  typedef std::map<Record*, SubRegMap> SubRegMaps;
+
+  SubRegMaps SubReg;
+  SubRegMap &inferSubRegIndices(Record *Reg);
+
+  // Composite SubRegIndex instances.
+  // Map (SubRegIndex,SubRegIndex) -> SubRegIndex
+  typedef DenseMap<std::pair<Record*,Record*>,Record*> CompositeMap;
+  CompositeMap Composite;
+
+  // Compute SubRegIndex compositions after inferSubRegIndices has run on all
+  // registers.
+  void computeComposites();
+};
+
+// Calculate all subregindices for Reg. Loopy subregs cause infinite recursion.
+RegisterMaps::SubRegMap &RegisterMaps::inferSubRegIndices(Record *Reg) {
+  SubRegMap &SRM = SubReg[Reg];
+  if (!SRM.empty())
+    return SRM;
+  std::vector<Record*> SubRegs = Reg->getValueAsListOfDefs("SubRegs");
+  std::vector<Record*> Indices = Reg->getValueAsListOfDefs("SubRegIndices");
+  if (SubRegs.size() != Indices.size())
+    throw "Register " + Reg->getName() + " SubRegIndices doesn't match SubRegs";
+
+  // First insert the direct subregs and make sure they are fully indexed.
+  for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) {
+    if (!SRM.insert(std::make_pair(Indices[i], SubRegs[i])).second)
+      throw "SubRegIndex " + Indices[i]->getName()
+        + " appears twice in Register " + Reg->getName();
+    inferSubRegIndices(SubRegs[i]);
+  }
+
+  // Keep track of inherited subregs and how they can be reached.
+  // Register -> (SubRegIndex, SubRegIndex)
+  typedef std::map<Record*, std::pair<Record*,Record*>, LessRecord> OrphanMap;
+  OrphanMap Orphans;
+
+  // Clone inherited subregs. Here the order is important - earlier subregs take
+  // precedence.
+  for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) {
+    SubRegMap &M = SubReg[SubRegs[i]];
+    for (SubRegMap::iterator si = M.begin(), se = M.end(); si != se; ++si)
+      if (!SRM.insert(*si).second)
+        Orphans[si->second] = std::make_pair(Indices[i], si->first);
+  }
+
+  // Finally process the composites.
+  ListInit *Comps = Reg->getValueAsListInit("CompositeIndices");
+  for (unsigned i = 0, e = Comps->size(); i != e; ++i) {
+    DagInit *Pat = dynamic_cast<DagInit*>(Comps->getElement(i));
+    if (!Pat)
+      throw "Invalid dag '" + Comps->getElement(i)->getAsString()
+        + "' in CompositeIndices";
+    DefInit *BaseIdxInit = dynamic_cast<DefInit*>(Pat->getOperator());
+    if (!BaseIdxInit || !BaseIdxInit->getDef()->isSubClassOf("SubRegIndex"))
+      throw "Invalid SubClassIndex in " + Pat->getAsString();
+
+    // Resolve list of subreg indices into R2.
+    Record *R2 = Reg;
+    for (DagInit::const_arg_iterator di = Pat->arg_begin(),
+         de = Pat->arg_end(); di != de; ++di) {
+      DefInit *IdxInit = dynamic_cast<DefInit*>(*di);
+      if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex"))
+        throw "Invalid SubClassIndex in " + Pat->getAsString();
+      SubRegMap::const_iterator ni = SubReg[R2].find(IdxInit->getDef());
+      if (ni == SubReg[R2].end())
+        throw "Composite " + Pat->getAsString() + " refers to bad index in "
+          + R2->getName();
+      R2 = ni->second;
+    }
+
+    // Insert composite index. Allow overriding inherited indices etc.
+    SRM[BaseIdxInit->getDef()] = R2;
+
+    // R2 is now directly addressable, no longer an orphan.
+    Orphans.erase(R2);
+  }
+
+  // Now, Orphans contains the inherited subregisters without a direct index.
+  if (!Orphans.empty()) {
+    errs() << "Error: Register " << getQualifiedName(Reg)
+           << " inherited subregisters without an index:\n";
+    for (OrphanMap::iterator i = Orphans.begin(), e = Orphans.end(); i != e;
+         ++i) {
+      errs() << "  " << getQualifiedName(i->first)
+             << " = " << i->second.first->getName()
+             << ", " << i->second.second->getName() << "\n";
+    }
+    abort();
+  }
+  return SRM;
+}
+
+void RegisterMaps::computeComposites() {
+  for (SubRegMaps::const_iterator sri = SubReg.begin(), sre = SubReg.end();
+       sri != sre; ++sri) {
+    Record *Reg1 = sri->first;
+    const SubRegMap &SRM1 = sri->second;
+    for (SubRegMap::const_iterator i1 = SRM1.begin(), e1 = SRM1.end();
+         i1 != e1; ++i1) {
+      Record *Idx1 = i1->first;
+      Record *Reg2 = i1->second;
+      // Ignore identity compositions.
+      if (Reg1 == Reg2)
+        continue;
+      // If Reg2 has no subregs, Idx1 doesn't compose.
+      if (!SubReg.count(Reg2))
+        continue;
+      const SubRegMap &SRM2 = SubReg[Reg2];
+      // Try composing Idx1 with another SubRegIndex.
+      for (SubRegMap::const_iterator i2 = SRM2.begin(), e2 = SRM2.end();
+           i2 != e2; ++i2) {
+        std::pair<Record*,Record*> IdxPair(Idx1, i2->first);
+        Record *Reg3 = i2->second;
+        // OK Reg1:IdxPair == Reg3. Find the index with Reg:Idx == Reg3.
+        for (SubRegMap::const_iterator i1d = SRM1.begin(), e1d = SRM1.end();
+             i1d != e1d; ++i1d) {
+          // Ignore identity compositions.
+          if (Reg2 == Reg3)
+            continue;
+          if (i1d->second == Reg3) {
+            std::pair<CompositeMap::iterator,bool> Ins =
+              Composite.insert(std::make_pair(IdxPair, i1d->first));
+            // Conflicting composition?
+            if (!Ins.second && Ins.first->second != i1d->first) {
+              errs() << "Error: SubRegIndex " << getQualifiedName(Idx1)
+                     << " and " << getQualifiedName(IdxPair.second)
+                     << " compose ambiguously as "
+                     << getQualifiedName(Ins.first->second) << " or "
+                     << getQualifiedName(i1d->first) << "\n";
+              abort();
+            }
+          }
+        }
+      }
+    }
+  }
+
+  // We don't care about the difference between (Idx1, Idx2) -> Idx2 and invalid
+  // compositions, so remove any mappings of that form.
+  for (CompositeMap::iterator i = Composite.begin(), e = Composite.end();
+       i != e;) {
+    CompositeMap::iterator j = i;
+    ++i;
+    if (j->first.second == j->second)
+      Composite.erase(j);
+  }
+}
+
+class RegisterSorter {
+private:
+  std::map<Record*, std::set<Record*>, LessRecord> &RegisterSubRegs;
+
+public:
+  RegisterSorter(std::map<Record*, std::set<Record*>, LessRecord> &RS)
+    : RegisterSubRegs(RS) {}
+
+  bool operator()(Record *RegA, Record *RegB) {
+    // B is sub-register of A.
+    return RegisterSubRegs.count(RegA) && RegisterSubRegs[RegA].count(RegB);
+  }
+};
+
+// RegisterInfoEmitter::run - Main register file description emitter.
+//
+void RegisterInfoEmitter::run(raw_ostream &OS) {
+  CodeGenTarget Target;
+  EmitSourceFileHeader("Register Information Source Fragment", OS);
+
+  OS << "namespace llvm {\n\n";
+
+  // Start out by emitting each of the register classes... to do this, we build
+  // a set of registers which belong to a register class, this is to ensure that
+  // each register is only in a single register class.
+  //
+  const std::vector<CodeGenRegisterClass> &RegisterClasses =
+    Target.getRegisterClasses();
+
+  // Loop over all of the register classes... emitting each one.
+  OS << "namespace {     // Register classes...\n";
+
+  // RegClassesBelongedTo - Keep track of which register classes each reg
+  // belongs to.
+  std::multimap<Record*, const CodeGenRegisterClass*> RegClassesBelongedTo;
+
+  // Emit the register enum value arrays for each RegisterClass
+  for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
+    const CodeGenRegisterClass &RC = RegisterClasses[rc];
+
+    // Give the register class a legal C name if it's anonymous.
+    std::string Name = RC.TheDef->getName();
+  
+    // Emit the register list now.
+    OS << "  // " << Name << " Register Class...\n"
+       << "  static const unsigned " << Name
+       << "[] = {\n    ";
+    for (unsigned i = 0, e = RC.Elements.size(); i != e; ++i) {
+      Record *Reg = RC.Elements[i];
+      OS << getQualifiedName(Reg) << ", ";
+
+      // Keep track of which regclasses this register is in.
+      RegClassesBelongedTo.insert(std::make_pair(Reg, &RC));
+    }
+    OS << "\n  };\n\n";
+  }
+
+  // Emit the ValueType arrays for each RegisterClass
+  for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
+    const CodeGenRegisterClass &RC = RegisterClasses[rc];
+    
+    // Give the register class a legal C name if it's anonymous.
+    std::string Name = RC.TheDef->getName() + "VTs";
+    
+    // Emit the register list now.
+    OS << "  // " << Name 
+       << " Register Class Value Types...\n"
+       << "  static const EVT " << Name
+       << "[] = {\n    ";
+    for (unsigned i = 0, e = RC.VTs.size(); i != e; ++i)
+      OS << getEnumName(RC.VTs[i]) << ", ";
+    OS << "MVT::Other\n  };\n\n";
+  }
+  OS << "}  // end anonymous namespace\n\n";
+  
+  // Now that all of the structs have been emitted, emit the instances.
+  if (!RegisterClasses.empty()) {
+    OS << "namespace " << RegisterClasses[0].Namespace
+       << " {   // Register class instances\n";
+    for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i)
+      OS << "  " << RegisterClasses[i].getName()  << "Class\t"
+         << RegisterClasses[i].getName() << "RegClass;\n";
+         
+    std::map<unsigned, std::set<unsigned> > SuperClassMap;
+    std::map<unsigned, std::set<unsigned> > SuperRegClassMap;
+    OS << "\n";
+
+    unsigned NumSubRegIndices = Target.getSubRegIndices().size();
+
+    if (NumSubRegIndices) {
+      // Emit the sub-register classes for each RegisterClass
+      for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
+        const CodeGenRegisterClass &RC = RegisterClasses[rc];
+        std::vector<Record*> SRC(NumSubRegIndices);
+        for (DenseMap<Record*,Record*>::const_iterator
+             i = RC.SubRegClasses.begin(),
+             e = RC.SubRegClasses.end(); i != e; ++i) {
+          // Build SRC array.
+          unsigned idx = Target.getSubRegIndexNo(i->first);
+          SRC.at(idx-1) = i->second;
+
+          // Find the register class number of i->second for SuperRegClassMap.
+          for (unsigned rc2 = 0, e2 = RegisterClasses.size(); rc2 != e2; ++rc2) {
+            const CodeGenRegisterClass &RC2 =  RegisterClasses[rc2];
+            if (RC2.TheDef == i->second) {
+              SuperRegClassMap[rc2].insert(rc);
+              break;
+            }
+          }
+        }
+
+        // Give the register class a legal C name if it's anonymous.
+        std::string Name = RC.TheDef->getName();
+
+        OS << "  // " << Name
+           << " Sub-register Classes...\n"
+           << "  static const TargetRegisterClass* const "
+           << Name << "SubRegClasses[] = {\n    ";
+
+        for (unsigned idx = 0; idx != NumSubRegIndices; ++idx) {
+          if (idx)
+            OS << ", ";
+          if (SRC[idx])
+            OS << "&" << getQualifiedName(SRC[idx]) << "RegClass";
+          else
+            OS << "0";
+        }
+        OS << "\n  };\n\n";
+      }
+
+      // Emit the super-register classes for each RegisterClass
+      for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
+        const CodeGenRegisterClass &RC = RegisterClasses[rc];
+
+        // Give the register class a legal C name if it's anonymous.
+        std::string Name = RC.TheDef->getName();
+
+        OS << "  // " << Name
+           << " Super-register Classes...\n"
+           << "  static const TargetRegisterClass* const "
+           << Name << "SuperRegClasses[] = {\n    ";
+
+        bool Empty = true;
+        std::map<unsigned, std::set<unsigned> >::iterator I =
+          SuperRegClassMap.find(rc);
+        if (I != SuperRegClassMap.end()) {
+          for (std::set<unsigned>::iterator II = I->second.begin(),
+                 EE = I->second.end(); II != EE; ++II) {
+            const CodeGenRegisterClass &RC2 = RegisterClasses[*II];
+            if (!Empty)
+              OS << ", ";
+            OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass";
+            Empty = false;
+          }
+        }
+
+        OS << (!Empty ? ", " : "") << "NULL";
+        OS << "\n  };\n\n";
+      }
+    } else {
+      // No subregindices in this target
+      OS << "  static const TargetRegisterClass* const "
+         << "NullRegClasses[] = { NULL };\n\n";
+    }
+
+    // Emit the sub-classes array for each RegisterClass
+    for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
+      const CodeGenRegisterClass &RC = RegisterClasses[rc];
+
+      // Give the register class a legal C name if it's anonymous.
+      std::string Name = RC.TheDef->getName();
+
+      std::set<Record*> RegSet;
+      for (unsigned i = 0, e = RC.Elements.size(); i != e; ++i) {
+        Record *Reg = RC.Elements[i];
+        RegSet.insert(Reg);
+      }
+
+      OS << "  // " << Name 
+         << " Register Class sub-classes...\n"
+         << "  static const TargetRegisterClass* const "
+         << Name << "Subclasses[] = {\n    ";
+
+      bool Empty = true;
+      for (unsigned rc2 = 0, e2 = RegisterClasses.size(); rc2 != e2; ++rc2) {
+        const CodeGenRegisterClass &RC2 = RegisterClasses[rc2];
+
+        // RC2 is a sub-class of RC if it is a valid replacement for any
+        // instruction operand where an RC register is required. It must satisfy
+        // these conditions:
+        //
+        // 1. All RC2 registers are also in RC.
+        // 2. The RC2 spill size must not be smaller that the RC spill size.
+        // 3. RC2 spill alignment must be compatible with RC.
+        //
+        // Sub-classes are used to determine if a virtual register can be used
+        // as an instruction operand, or if it must be copied first.
+
+        if (rc == rc2 || RC2.Elements.size() > RC.Elements.size() ||
+            (RC.SpillAlignment && RC2.SpillAlignment % RC.SpillAlignment) ||
+            RC.SpillSize > RC2.SpillSize || !isSubRegisterClass(RC2, RegSet))
+          continue;
+      
+        if (!Empty) OS << ", ";
+        OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass";
+        Empty = false;
+
+        std::map<unsigned, std::set<unsigned> >::iterator SCMI =
+          SuperClassMap.find(rc2);
+        if (SCMI == SuperClassMap.end()) {
+          SuperClassMap.insert(std::make_pair(rc2, std::set<unsigned>()));
+          SCMI = SuperClassMap.find(rc2);
+        }
+        SCMI->second.insert(rc);
+      }
+
+      OS << (!Empty ? ", " : "") << "NULL";
+      OS << "\n  };\n\n";
+    }
+
+    for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
+      const CodeGenRegisterClass &RC = RegisterClasses[rc];
+
+      // Give the register class a legal C name if it's anonymous.
+      std::string Name = RC.TheDef->getName();
+
+      OS << "  // " << Name 
+         << " Register Class super-classes...\n"
+         << "  static const TargetRegisterClass* const "
+         << Name << "Superclasses[] = {\n    ";
+
+      bool Empty = true;
+      std::map<unsigned, std::set<unsigned> >::iterator I =
+        SuperClassMap.find(rc);
+      if (I != SuperClassMap.end()) {
+        for (std::set<unsigned>::iterator II = I->second.begin(),
+               EE = I->second.end(); II != EE; ++II) {
+          const CodeGenRegisterClass &RC2 = RegisterClasses[*II];
+          if (!Empty) OS << ", ";
+          OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass";
+          Empty = false;        
+        }
+      }
+
+      OS << (!Empty ? ", " : "") << "NULL";
+      OS << "\n  };\n\n";
+    }
+
+
+    for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
+      const CodeGenRegisterClass &RC = RegisterClasses[i];
+      OS << RC.MethodBodies << "\n";
+      OS << RC.getName() << "Class::" << RC.getName() 
+         << "Class()  : TargetRegisterClass("
+         << RC.getName() + "RegClassID" << ", "
+         << '\"' << RC.getName() << "\", "
+         << RC.getName() + "VTs" << ", "
+         << RC.getName() + "Subclasses" << ", "
+         << RC.getName() + "Superclasses" << ", "
+         << (NumSubRegIndices ? RC.getName() + "Sub" : std::string("Null"))
+         << "RegClasses, "
+         << (NumSubRegIndices ? RC.getName() + "Super" : std::string("Null"))
+         << "RegClasses, "
+         << RC.SpillSize/8 << ", "
+         << RC.SpillAlignment/8 << ", "
+         << RC.CopyCost << ", "
+         << RC.getName() << ", " << RC.getName() << " + " << RC.Elements.size()
+         << ") {}\n";
+    }
+  
+    OS << "}\n";
+  }
+
+  OS << "\nnamespace {\n";
+  OS << "  const TargetRegisterClass* const RegisterClasses[] = {\n";
+  for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i)
+    OS << "    &" << getQualifiedName(RegisterClasses[i].TheDef)
+       << "RegClass,\n";
+  OS << "  };\n";
+
+  // Emit register sub-registers / super-registers, aliases...
+  std::map<Record*, std::set<Record*>, LessRecord> RegisterSubRegs;
+  std::map<Record*, std::set<Record*>, LessRecord> RegisterSuperRegs;
+  std::map<Record*, std::set<Record*>, LessRecord> RegisterAliases;
+  typedef std::map<Record*, std::vector<int64_t>, LessRecord> DwarfRegNumsMapTy;
+  DwarfRegNumsMapTy DwarfRegNums;
+  
+  const std::vector<CodeGenRegister> &Regs = Target.getRegisters();
+
+  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+    Record *R = Regs[i].TheDef;
+    std::vector<Record*> LI = Regs[i].TheDef->getValueAsListOfDefs("Aliases");
+    // Add information that R aliases all of the elements in the list... and
+    // that everything in the list aliases R.
+    for (unsigned j = 0, e = LI.size(); j != e; ++j) {
+      Record *Reg = LI[j];
+      if (RegisterAliases[R].count(Reg))
+        errs() << "Warning: register alias between " << getQualifiedName(R)
+               << " and " << getQualifiedName(Reg)
+               << " specified multiple times!\n";
+      RegisterAliases[R].insert(Reg);
+
+      if (RegisterAliases[Reg].count(R))
+        errs() << "Warning: register alias between " << getQualifiedName(R)
+               << " and " << getQualifiedName(Reg)
+               << " specified multiple times!\n";
+      RegisterAliases[Reg].insert(R);
+    }
+  }
+
+  // Process sub-register sets.
+  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+    Record *R = Regs[i].TheDef;
+    std::vector<Record*> LI = Regs[i].TheDef->getValueAsListOfDefs("SubRegs");
+    // Process sub-register set and add aliases information.
+    for (unsigned j = 0, e = LI.size(); j != e; ++j) {
+      Record *SubReg = LI[j];
+      if (RegisterSubRegs[R].count(SubReg))
+        errs() << "Warning: register " << getQualifiedName(SubReg)
+               << " specified as a sub-register of " << getQualifiedName(R)
+               << " multiple times!\n";
+      addSubSuperReg(R, SubReg, RegisterSubRegs, RegisterSuperRegs,
+                     RegisterAliases);
+    }
+  }
+  
+  // Print the SubregHashTable, a simple quadratically probed
+  // hash table for determining if a register is a subregister
+  // of another register.
+  unsigned NumSubRegs = 0;
+  std::map<Record*, unsigned> RegNo;
+  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+    RegNo[Regs[i].TheDef] = i;
+    NumSubRegs += RegisterSubRegs[Regs[i].TheDef].size();
+  }
+  
+  unsigned SubregHashTableSize = 2 * NextPowerOf2(2 * NumSubRegs);
+  unsigned* SubregHashTable = new unsigned[2 * SubregHashTableSize];
+  std::fill(SubregHashTable, SubregHashTable + 2 * SubregHashTableSize, ~0U);
+  
+  unsigned hashMisses = 0;
+  
+  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+    Record* R = Regs[i].TheDef;
+    for (std::set<Record*>::iterator I = RegisterSubRegs[R].begin(),
+         E = RegisterSubRegs[R].end(); I != E; ++I) {
+      Record* RJ = *I;
+      // We have to increase the indices of both registers by one when
+      // computing the hash because, in the generated code, there
+      // will be an extra empty slot at register 0.
+      size_t index = ((i+1) + (RegNo[RJ]+1) * 37) & (SubregHashTableSize-1);
+      unsigned ProbeAmt = 2;
+      while (SubregHashTable[index*2] != ~0U &&
+             SubregHashTable[index*2+1] != ~0U) {
+        index = (index + ProbeAmt) & (SubregHashTableSize-1);
+        ProbeAmt += 2;
+        
+        hashMisses++;
+      }
+      
+      SubregHashTable[index*2] = i;
+      SubregHashTable[index*2+1] = RegNo[RJ];
+    }
+  }
+  
+  OS << "\n\n  // Number of hash collisions: " << hashMisses << "\n";
+  
+  if (SubregHashTableSize) {
+    std::string Namespace = Regs[0].TheDef->getValueAsString("Namespace");
+    
+    OS << "  const unsigned SubregHashTable[] = { ";
+    for (unsigned i = 0; i < SubregHashTableSize - 1; ++i) {
+      if (i != 0)
+        // Insert spaces for nice formatting.
+        OS << "                                       ";
+      
+      if (SubregHashTable[2*i] != ~0U) {
+        OS << getQualifiedName(Regs[SubregHashTable[2*i]].TheDef) << ", "
+           << getQualifiedName(Regs[SubregHashTable[2*i+1]].TheDef) << ", \n";
+      } else {
+        OS << Namespace << "::NoRegister, " << Namespace << "::NoRegister, \n";
+      }
+    }
+    
+    unsigned Idx = SubregHashTableSize*2-2;
+    if (SubregHashTable[Idx] != ~0U) {
+      OS << "                                       "
+         << getQualifiedName(Regs[SubregHashTable[Idx]].TheDef) << ", "
+         << getQualifiedName(Regs[SubregHashTable[Idx+1]].TheDef) << " };\n";
+    } else {
+      OS << Namespace << "::NoRegister, " << Namespace << "::NoRegister };\n";
+    }
+    
+    OS << "  const unsigned SubregHashTableSize = "
+       << SubregHashTableSize << ";\n";
+  } else {
+    OS << "  const unsigned SubregHashTable[] = { ~0U, ~0U };\n"
+       << "  const unsigned SubregHashTableSize = 1;\n";
+  }
+  
+  delete [] SubregHashTable;
+
+
+  // Print the AliasHashTable, a simple quadratically probed
+  // hash table for determining if a register aliases another register.
+  unsigned NumAliases = 0;
+  RegNo.clear();
+  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+    RegNo[Regs[i].TheDef] = i;
+    NumAliases += RegisterAliases[Regs[i].TheDef].size();
+  }
+  
+  unsigned AliasesHashTableSize = 2 * NextPowerOf2(2 * NumAliases);
+  unsigned* AliasesHashTable = new unsigned[2 * AliasesHashTableSize];
+  std::fill(AliasesHashTable, AliasesHashTable + 2 * AliasesHashTableSize, ~0U);
+  
+  hashMisses = 0;
+  
+  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+    Record* R = Regs[i].TheDef;
+    for (std::set<Record*>::iterator I = RegisterAliases[R].begin(),
+         E = RegisterAliases[R].end(); I != E; ++I) {
+      Record* RJ = *I;
+      // We have to increase the indices of both registers by one when
+      // computing the hash because, in the generated code, there
+      // will be an extra empty slot at register 0.
+      size_t index = ((i+1) + (RegNo[RJ]+1) * 37) & (AliasesHashTableSize-1);
+      unsigned ProbeAmt = 2;
+      while (AliasesHashTable[index*2] != ~0U &&
+             AliasesHashTable[index*2+1] != ~0U) {
+        index = (index + ProbeAmt) & (AliasesHashTableSize-1);
+        ProbeAmt += 2;
+        
+        hashMisses++;
+      }
+      
+      AliasesHashTable[index*2] = i;
+      AliasesHashTable[index*2+1] = RegNo[RJ];
+    }
+  }
+  
+  OS << "\n\n  // Number of hash collisions: " << hashMisses << "\n";
+  
+  if (AliasesHashTableSize) {
+    std::string Namespace = Regs[0].TheDef->getValueAsString("Namespace");
+    
+    OS << "  const unsigned AliasesHashTable[] = { ";
+    for (unsigned i = 0; i < AliasesHashTableSize - 1; ++i) {
+      if (i != 0)
+        // Insert spaces for nice formatting.
+        OS << "                                       ";
+      
+      if (AliasesHashTable[2*i] != ~0U) {
+        OS << getQualifiedName(Regs[AliasesHashTable[2*i]].TheDef) << ", "
+           << getQualifiedName(Regs[AliasesHashTable[2*i+1]].TheDef) << ", \n";
+      } else {
+        OS << Namespace << "::NoRegister, " << Namespace << "::NoRegister, \n";
+      }
+    }
+    
+    unsigned Idx = AliasesHashTableSize*2-2;
+    if (AliasesHashTable[Idx] != ~0U) {
+      OS << "                                       "
+         << getQualifiedName(Regs[AliasesHashTable[Idx]].TheDef) << ", "
+         << getQualifiedName(Regs[AliasesHashTable[Idx+1]].TheDef) << " };\n";
+    } else {
+      OS << Namespace << "::NoRegister, " << Namespace << "::NoRegister };\n";
+    }
+    
+    OS << "  const unsigned AliasesHashTableSize = "
+       << AliasesHashTableSize << ";\n";
+  } else {
+    OS << "  const unsigned AliasesHashTable[] = { ~0U, ~0U };\n"
+       << "  const unsigned AliasesHashTableSize = 1;\n";
+  }
+  
+  delete [] AliasesHashTable;
+
+  if (!RegisterAliases.empty())
+    OS << "\n\n  // Register Alias Sets...\n";
+
+  // Emit the empty alias list
+  OS << "  const unsigned Empty_AliasSet[] = { 0 };\n";
+  // Loop over all of the registers which have aliases, emitting the alias list
+  // to memory.
+  for (std::map<Record*, std::set<Record*>, LessRecord >::iterator
+         I = RegisterAliases.begin(), E = RegisterAliases.end(); I != E; ++I) {
+    if (I->second.empty())
+      continue;
+    OS << "  const unsigned " << I->first->getName() << "_AliasSet[] = { ";
+    for (std::set<Record*>::iterator ASI = I->second.begin(),
+           E = I->second.end(); ASI != E; ++ASI)
+      OS << getQualifiedName(*ASI) << ", ";
+    OS << "0 };\n";
+  }
+
+  if (!RegisterSubRegs.empty())
+    OS << "\n\n  // Register Sub-registers Sets...\n";
+
+  // Emit the empty sub-registers list
+  OS << "  const unsigned Empty_SubRegsSet[] = { 0 };\n";
+  // Loop over all of the registers which have sub-registers, emitting the
+  // sub-registers list to memory.
+  for (std::map<Record*, std::set<Record*>, LessRecord>::iterator
+         I = RegisterSubRegs.begin(), E = RegisterSubRegs.end(); I != E; ++I) {
+   if (I->second.empty())
+     continue;
+    OS << "  const unsigned " << I->first->getName() << "_SubRegsSet[] = { ";
+    std::vector<Record*> SubRegsVector;
+    for (std::set<Record*>::iterator ASI = I->second.begin(),
+           E = I->second.end(); ASI != E; ++ASI)
+      SubRegsVector.push_back(*ASI);
+    RegisterSorter RS(RegisterSubRegs);
+    std::stable_sort(SubRegsVector.begin(), SubRegsVector.end(), RS);
+    for (unsigned i = 0, e = SubRegsVector.size(); i != e; ++i)
+      OS << getQualifiedName(SubRegsVector[i]) << ", ";
+    OS << "0 };\n";
+  }
+
+  if (!RegisterSuperRegs.empty())
+    OS << "\n\n  // Register Super-registers Sets...\n";
+
+  // Emit the empty super-registers list
+  OS << "  const unsigned Empty_SuperRegsSet[] = { 0 };\n";
+  // Loop over all of the registers which have super-registers, emitting the
+  // super-registers list to memory.
+  for (std::map<Record*, std::set<Record*>, LessRecord >::iterator
+         I = RegisterSuperRegs.begin(), E = RegisterSuperRegs.end(); I != E; ++I) {
+    if (I->second.empty())
+      continue;
+    OS << "  const unsigned " << I->first->getName() << "_SuperRegsSet[] = { ";
+
+    std::vector<Record*> SuperRegsVector;
+    for (std::set<Record*>::iterator ASI = I->second.begin(),
+           E = I->second.end(); ASI != E; ++ASI)
+      SuperRegsVector.push_back(*ASI);
+    RegisterSorter RS(RegisterSubRegs);
+    std::stable_sort(SuperRegsVector.begin(), SuperRegsVector.end(), RS);
+    for (unsigned i = 0, e = SuperRegsVector.size(); i != e; ++i)
+      OS << getQualifiedName(SuperRegsVector[i]) << ", ";
+    OS << "0 };\n";
+  }
+
+  OS<<"\n  const TargetRegisterDesc RegisterDescriptors[] = { // Descriptors\n";
+  OS << "    { \"NOREG\",\t0,\t0,\t0 },\n";
+
+  // Now that register alias and sub-registers sets have been emitted, emit the
+  // register descriptors now.
+  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+    const CodeGenRegister &Reg = Regs[i];
+    OS << "    { \"";
+    OS << Reg.getName() << "\",\t";
+    if (!RegisterAliases[Reg.TheDef].empty())
+      OS << Reg.getName() << "_AliasSet,\t";
+    else
+      OS << "Empty_AliasSet,\t";
+    if (!RegisterSubRegs[Reg.TheDef].empty())
+      OS << Reg.getName() << "_SubRegsSet,\t";
+    else
+      OS << "Empty_SubRegsSet,\t";
+    if (!RegisterSuperRegs[Reg.TheDef].empty())
+      OS << Reg.getName() << "_SuperRegsSet },\n";
+    else
+      OS << "Empty_SuperRegsSet },\n";
+  }
+  OS << "  };\n";      // End of register descriptors...
+
+  // Emit SubRegIndex names, skipping 0
+  const std::vector<Record*> SubRegIndices = Target.getSubRegIndices();
+  OS << "\n  const char *const SubRegIndexTable[] = { \"";
+  for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
+    OS << SubRegIndices[i]->getName();
+    if (i+1 != e)
+      OS << "\", \"";
+  }
+  OS << "\" };\n\n";
+  OS << "}\n\n";       // End of anonymous namespace...
+
+  std::string ClassName = Target.getName() + "GenRegisterInfo";
+
+  // Calculate the mapping of subregister+index pairs to physical registers.
+  RegisterMaps RegMaps;
+
+  // Emit the subregister + index mapping function based on the information
+  // calculated above.
+  OS << "unsigned " << ClassName
+     << "::getSubReg(unsigned RegNo, unsigned Index) const {\n"
+     << "  switch (RegNo) {\n"
+     << "  default:\n    return 0;\n";
+  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+    RegisterMaps::SubRegMap &SRM = RegMaps.inferSubRegIndices(Regs[i].TheDef);
+    if (SRM.empty())
+      continue;
+    OS << "  case " << getQualifiedName(Regs[i].TheDef) << ":\n";
+    OS << "    switch (Index) {\n";
+    OS << "    default: return 0;\n";
+    for (RegisterMaps::SubRegMap::const_iterator ii = SRM.begin(),
+         ie = SRM.end(); ii != ie; ++ii)
+      OS << "    case " << getQualifiedName(ii->first)
+         << ": return " << getQualifiedName(ii->second) << ";\n";
+    OS << "    };\n" << "    break;\n";
+  }
+  OS << "  };\n";
+  OS << "  return 0;\n";
+  OS << "}\n\n";
+
+  OS << "unsigned " << ClassName
+     << "::getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const {\n"
+     << "  switch (RegNo) {\n"
+     << "  default:\n    return 0;\n";
+   for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+     RegisterMaps::SubRegMap &SRM = RegMaps.SubReg[Regs[i].TheDef];
+     if (SRM.empty())
+       continue;
+    OS << "  case " << getQualifiedName(Regs[i].TheDef) << ":\n";
+    for (RegisterMaps::SubRegMap::const_iterator ii = SRM.begin(),
+         ie = SRM.end(); ii != ie; ++ii)
+      OS << "    if (SubRegNo == " << getQualifiedName(ii->second)
+         << ")  return " << getQualifiedName(ii->first) << ";\n";
+    OS << "    return 0;\n";
+  }
+  OS << "  };\n";
+  OS << "  return 0;\n";
+  OS << "}\n\n";
+
+  // Emit composeSubRegIndices
+  RegMaps.computeComposites();
+  OS << "unsigned " << ClassName
+     << "::composeSubRegIndices(unsigned IdxA, unsigned IdxB) const {\n"
+     << "  switch (IdxA) {\n"
+     << "  default:\n    return IdxB;\n";
+  for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
+    bool Open = false;
+    for (unsigned j = 0; j != e; ++j) {
+      if (Record *Comp = RegMaps.Composite.lookup(
+                          std::make_pair(SubRegIndices[i], SubRegIndices[j]))) {
+        if (!Open) {
+          OS << "  case " << getQualifiedName(SubRegIndices[i])
+             << ": switch(IdxB) {\n    default: return IdxB;\n";
+          Open = true;
+        }
+        OS << "    case " << getQualifiedName(SubRegIndices[j])
+           << ": return " << getQualifiedName(Comp) << ";\n";
+      }
+    }
+    if (Open)
+      OS << "    }\n";
+  }
+  OS << "  }\n}\n\n";
+
+  // Emit the constructor of the class...
+  OS << ClassName << "::" << ClassName
+     << "(int CallFrameSetupOpcode, int CallFrameDestroyOpcode)\n"
+     << "  : TargetRegisterInfo(RegisterDescriptors, " << Regs.size()+1
+     << ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n"
+     << "                 SubRegIndexTable,\n"
+     << "                 CallFrameSetupOpcode, CallFrameDestroyOpcode,\n"
+     << "                 SubregHashTable, SubregHashTableSize,\n"
+     << "                 AliasesHashTable, AliasesHashTableSize) {\n"
+     << "}\n\n";
+
+  // Collect all information about dwarf register numbers
+
+  // First, just pull all provided information to the map
+  unsigned maxLength = 0;
+  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+    Record *Reg = Regs[i].TheDef;
+    std::vector<int64_t> RegNums = Reg->getValueAsListOfInts("DwarfNumbers");
+    maxLength = std::max((size_t)maxLength, RegNums.size());
+    if (DwarfRegNums.count(Reg))
+      errs() << "Warning: DWARF numbers for register " << getQualifiedName(Reg)
+             << "specified multiple times\n";
+    DwarfRegNums[Reg] = RegNums;
+  }
+
+  // Now we know maximal length of number list. Append -1's, where needed
+  for (DwarfRegNumsMapTy::iterator 
+       I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I)
+    for (unsigned i = I->second.size(), e = maxLength; i != e; ++i)
+      I->second.push_back(-1);
+
+  // Emit information about the dwarf register numbers.
+  OS << "int " << ClassName << "::getDwarfRegNumFull(unsigned RegNum, "
+     << "unsigned Flavour) const {\n"
+     << "  switch (Flavour) {\n"
+     << "  default:\n"
+     << "    assert(0 && \"Unknown DWARF flavour\");\n"
+     << "    return -1;\n";
+  
+  for (unsigned i = 0, e = maxLength; i != e; ++i) {
+    OS << "  case " << i << ":\n"
+       << "    switch (RegNum) {\n"
+       << "    default:\n"
+       << "      assert(0 && \"Invalid RegNum\");\n"
+       << "      return -1;\n";
+    
+    // Sort by name to get a stable order.
+    
+
+    for (DwarfRegNumsMapTy::iterator 
+           I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) {
+      int RegNo = I->second[i];
+      if (RegNo != -2)
+        OS << "    case " << getQualifiedName(I->first) << ":\n"
+           << "      return " << RegNo << ";\n";
+      else
+        OS << "    case " << getQualifiedName(I->first) << ":\n"
+           << "      assert(0 && \"Invalid register for this mode\");\n"
+           << "      return -1;\n";
+    }
+    OS << "    };\n";
+  }
+    
+  OS << "  };\n}\n\n";
+
+  OS << "} // End llvm namespace \n";
+}
diff --git a/src/LLVM/utils/TableGen/RegisterInfoEmitter.h b/src/LLVM/utils/TableGen/RegisterInfoEmitter.h
new file mode 100644
index 0000000..1456b4f
--- /dev/null
+++ b/src/LLVM/utils/TableGen/RegisterInfoEmitter.h
@@ -0,0 +1,40 @@
+//===- RegisterInfoEmitter.h - Generate a Register File Desc. ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend is responsible for emitting a description of a target
+// register file for a code generator.  It uses instances of the Register,
+// RegisterAliases, and RegisterClass classes to gather this information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef REGISTER_INFO_EMITTER_H
+#define REGISTER_INFO_EMITTER_H
+
+#include "TableGenBackend.h"
+
+namespace llvm {
+
+class RegisterInfoEmitter : public TableGenBackend {
+  RecordKeeper &Records;
+public:
+  RegisterInfoEmitter(RecordKeeper &R) : Records(R) {}
+
+  // run - Output the register file description, returning true on failure.
+  void run(raw_ostream &o);
+
+  // runHeader - Emit a header fragment for the register info emitter.
+  void runHeader(raw_ostream &o);
+
+  // runEnums - Print out enum values for all of the registers.
+  void runEnums(raw_ostream &o);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/utils/TableGen/StringToOffsetTable.h b/src/LLVM/utils/TableGen/StringToOffsetTable.h
new file mode 100644
index 0000000..ac9422c
--- /dev/null
+++ b/src/LLVM/utils/TableGen/StringToOffsetTable.h
@@ -0,0 +1,81 @@
+//===- StringToOffsetTable.h - Emit a big concatenated string ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TBLGEN_STRING_TO_OFFSET_TABLE_H
+#define TBLGEN_STRING_TO_OFFSET_TABLE_H
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+/// StringToOffsetTable - This class uniques a bunch of nul-terminated strings
+/// and keeps track of their offset in a massive contiguous string allocation.
+/// It can then output this string blob and use indexes into the string to
+/// reference each piece.
+class StringToOffsetTable {
+  StringMap<unsigned> StringOffset;
+  std::string AggregateString;
+public:
+  
+  unsigned GetOrAddStringOffset(StringRef Str) {
+    unsigned &Entry = StringOffset[Str];
+    if (Entry == 0) {
+      // Add the string to the aggregate if this is the first time found.
+      Entry = AggregateString.size();
+      AggregateString.append(Str.begin(), Str.end());
+      AggregateString += '\0';
+    }
+    
+    return Entry;
+  }
+  
+  void EmitString(raw_ostream &O) {
+    // Escape the string.
+    SmallString<256> Str;
+    raw_svector_ostream(Str).write_escaped(AggregateString);
+    AggregateString = Str.str();
+
+    O << "    \"";
+    unsigned CharsPrinted = 0;
+    for (unsigned i = 0, e = AggregateString.size(); i != e; ++i) {
+      if (CharsPrinted > 70) {
+        O << "\"\n    \"";
+        CharsPrinted = 0;
+      }
+      O << AggregateString[i];
+      ++CharsPrinted;
+      
+      // Print escape sequences all together.
+      if (AggregateString[i] != '\\')
+        continue;
+      
+      assert(i+1 < AggregateString.size() && "Incomplete escape sequence!");
+      if (isdigit(AggregateString[i+1])) {
+        assert(isdigit(AggregateString[i+2]) && 
+               isdigit(AggregateString[i+3]) &&
+               "Expected 3 digit octal escape!");
+        O << AggregateString[++i];
+        O << AggregateString[++i];
+        O << AggregateString[++i];
+        CharsPrinted += 3;
+      } else {
+        O << AggregateString[++i];
+        ++CharsPrinted;
+      }
+    }
+    O << "\"";
+  }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/src/LLVM/utils/TableGen/SubtargetEmitter.cpp b/src/LLVM/utils/TableGen/SubtargetEmitter.cpp
new file mode 100644
index 0000000..b04eaf8
--- /dev/null
+++ b/src/LLVM/utils/TableGen/SubtargetEmitter.cpp
@@ -0,0 +1,605 @@
+//===- SubtargetEmitter.cpp - Generate subtarget enumerations -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend emits subtarget enumerations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SubtargetEmitter.h"
+#include "CodeGenTarget.h"
+#include "Record.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Debug.h"
+#include <algorithm>
+using namespace llvm;
+
+//
+// Enumeration - Emit the specified class as an enumeration.
+//
+void SubtargetEmitter::Enumeration(raw_ostream &OS,
+                                   const char *ClassName,
+                                   bool isBits) {
+  // Get all records of class and sort
+  std::vector<Record*> DefList = Records.getAllDerivedDefinitions(ClassName);
+  std::sort(DefList.begin(), DefList.end(), LessRecord());
+
+  // Open enumeration
+  OS << "enum {\n";
+  
+  // For each record
+  for (unsigned i = 0, N = DefList.size(); i < N;) {
+    // Next record
+    Record *Def = DefList[i];
+    
+    // Get and emit name
+    OS << "  " << Def->getName();
+    
+    // If bit flags then emit expression (1 << i)
+    if (isBits)  OS << " = " << " 1 << " << i;
+
+    // Depending on 'if more in the list' emit comma
+    if (++i < N) OS << ",";
+    
+    OS << "\n";
+  }
+  
+  // Close enumeration
+  OS << "};\n";
+}
+
+//
+// FeatureKeyValues - Emit data of all the subtarget features.  Used by the
+// command line.
+//
+void SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) {
+  // Gather and sort all the features
+  std::vector<Record*> FeatureList =
+                           Records.getAllDerivedDefinitions("SubtargetFeature");
+  std::sort(FeatureList.begin(), FeatureList.end(), LessRecordFieldName());
+
+  // Begin feature table
+  OS << "// Sorted (by key) array of values for CPU features.\n"
+     << "static const llvm::SubtargetFeatureKV FeatureKV[] = {\n";
+  
+  // For each feature
+  for (unsigned i = 0, N = FeatureList.size(); i < N; ++i) {
+    // Next feature
+    Record *Feature = FeatureList[i];
+
+    const std::string &Name = Feature->getName();
+    const std::string &CommandLineName = Feature->getValueAsString("Name");
+    const std::string &Desc = Feature->getValueAsString("Desc");
+    
+    if (CommandLineName.empty()) continue;
+    
+    // Emit as { "feature", "description", featureEnum, i1 | i2 | ... | in }
+    OS << "  { "
+       << "\"" << CommandLineName << "\", "
+       << "\"" << Desc << "\", "
+       << Name << ", ";
+
+    const std::vector<Record*> &ImpliesList = 
+      Feature->getValueAsListOfDefs("Implies");
+    
+    if (ImpliesList.empty()) {
+      OS << "0";
+    } else {
+      for (unsigned j = 0, M = ImpliesList.size(); j < M;) {
+        OS << ImpliesList[j]->getName();
+        if (++j < M) OS << " | ";
+      }
+    }
+
+    OS << " }";
+    
+    // Depending on 'if more in the list' emit comma
+    if ((i + 1) < N) OS << ",";
+    
+    OS << "\n";
+  }
+  
+  // End feature table
+  OS << "};\n";
+
+  // Emit size of table
+  OS<<"\nenum {\n";
+  OS<<"  FeatureKVSize = sizeof(FeatureKV)/sizeof(llvm::SubtargetFeatureKV)\n";
+  OS<<"};\n";
+}
+
+//
+// CPUKeyValues - Emit data of all the subtarget processors.  Used by command
+// line.
+//
+void SubtargetEmitter::CPUKeyValues(raw_ostream &OS) {
+  // Gather and sort processor information
+  std::vector<Record*> ProcessorList =
+                          Records.getAllDerivedDefinitions("Processor");
+  std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
+
+  // Begin processor table
+  OS << "// Sorted (by key) array of values for CPU subtype.\n"
+     << "static const llvm::SubtargetFeatureKV SubTypeKV[] = {\n";
+     
+  // For each processor
+  for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
+    // Next processor
+    Record *Processor = ProcessorList[i];
+
+    const std::string &Name = Processor->getValueAsString("Name");
+    const std::vector<Record*> &FeatureList = 
+      Processor->getValueAsListOfDefs("Features");
+    
+    // Emit as { "cpu", "description", f1 | f2 | ... fn },
+    OS << "  { "
+       << "\"" << Name << "\", "
+       << "\"Select the " << Name << " processor\", ";
+    
+    if (FeatureList.empty()) {
+      OS << "0";
+    } else {
+      for (unsigned j = 0, M = FeatureList.size(); j < M;) {
+        OS << FeatureList[j]->getName();
+        if (++j < M) OS << " | ";
+      }
+    }
+    
+    // The "0" is for the "implies" section of this data structure.
+    OS << ", 0 }";
+    
+    // Depending on 'if more in the list' emit comma
+    if (++i < N) OS << ",";
+    
+    OS << "\n";
+  }
+  
+  // End processor table
+  OS << "};\n";
+
+  // Emit size of table
+  OS<<"\nenum {\n";
+  OS<<"  SubTypeKVSize = sizeof(SubTypeKV)/sizeof(llvm::SubtargetFeatureKV)\n";
+  OS<<"};\n";
+}
+
+//
+// CollectAllItinClasses - Gathers and enumerates all the itinerary classes.
+// Returns itinerary class count.
+//
+unsigned SubtargetEmitter::CollectAllItinClasses(raw_ostream &OS,
+                              std::map<std::string, unsigned> &ItinClassesMap) {
+  // Gather and sort all itinerary classes
+  std::vector<Record*> ItinClassList =
+                            Records.getAllDerivedDefinitions("InstrItinClass");
+  std::sort(ItinClassList.begin(), ItinClassList.end(), LessRecord());
+
+  // For each itinerary class
+  unsigned N = ItinClassList.size();
+  for (unsigned i = 0; i < N; i++) {
+    // Next itinerary class
+    const Record *ItinClass = ItinClassList[i];
+    // Get name of itinerary class
+    // Assign itinerary class a unique number
+    ItinClassesMap[ItinClass->getName()] = i;
+  }
+  
+  // Emit size of table
+  OS<<"\nenum {\n";
+  OS<<"  ItinClassesSize = " << N << "\n";
+  OS<<"};\n";
+
+  // Return itinerary class count
+  return N;
+}
+
+//
+// FormItineraryStageString - Compose a string containing the stage
+// data initialization for the specified itinerary.  N is the number
+// of stages.
+//
+void SubtargetEmitter::FormItineraryStageString(const std::string &Name,
+                                                Record *ItinData,
+                                                std::string &ItinString,
+                                                unsigned &NStages) {
+  // Get states list
+  const std::vector<Record*> &StageList =
+    ItinData->getValueAsListOfDefs("Stages");
+
+  // For each stage
+  unsigned N = NStages = StageList.size();
+  for (unsigned i = 0; i < N;) {
+    // Next stage
+    const Record *Stage = StageList[i];
+  
+    // Form string as ,{ cycles, u1 | u2 | ... | un, timeinc, kind }
+    int Cycles = Stage->getValueAsInt("Cycles");
+    ItinString += "  { " + itostr(Cycles) + ", ";
+    
+    // Get unit list
+    const std::vector<Record*> &UnitList = Stage->getValueAsListOfDefs("Units");
+    
+    // For each unit
+    for (unsigned j = 0, M = UnitList.size(); j < M;) {
+      // Add name and bitwise or
+      ItinString += Name + "FU::" + UnitList[j]->getName();
+      if (++j < M) ItinString += " | ";
+    }
+    
+    int TimeInc = Stage->getValueAsInt("TimeInc");
+    ItinString += ", " + itostr(TimeInc);
+
+    int Kind = Stage->getValueAsInt("Kind");
+    ItinString += ", (llvm::InstrStage::ReservationKinds)" + itostr(Kind);
+
+    // Close off stage
+    ItinString += " }";
+    if (++i < N) ItinString += ", ";
+  }
+}
+
+//
+// FormItineraryOperandCycleString - Compose a string containing the
+// operand cycle initialization for the specified itinerary.  N is the
+// number of operands that has cycles specified.
+//
+void SubtargetEmitter::FormItineraryOperandCycleString(Record *ItinData,
+                         std::string &ItinString, unsigned &NOperandCycles) {
+  // Get operand cycle list
+  const std::vector<int64_t> &OperandCycleList =
+    ItinData->getValueAsListOfInts("OperandCycles");
+
+  // For each operand cycle
+  unsigned N = NOperandCycles = OperandCycleList.size();
+  for (unsigned i = 0; i < N;) {
+    // Next operand cycle
+    const int OCycle = OperandCycleList[i];
+  
+    ItinString += "  " + itostr(OCycle);
+    if (++i < N) ItinString += ", ";
+  }
+}
+
+//
+// EmitStageAndOperandCycleData - Generate unique itinerary stages and
+// operand cycle tables.  Record itineraries for processors.
+//
+void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
+       unsigned NItinClasses,
+       std::map<std::string, unsigned> &ItinClassesMap, 
+       std::vector<std::vector<InstrItinerary> > &ProcList) {
+  // Gather processor iteraries
+  std::vector<Record*> ProcItinList =
+                       Records.getAllDerivedDefinitions("ProcessorItineraries");
+  
+  // If just no itinerary then don't bother
+  if (ProcItinList.size() < 2) return;
+
+  // Emit functional units for all the itineraries.
+  for (unsigned i = 0, N = ProcItinList.size(); i < N; ++i) {
+    // Next record
+    Record *Proc = ProcItinList[i];
+
+    std::vector<Record*> FUs = Proc->getValueAsListOfDefs("FU");
+    if (FUs.empty())
+      continue;
+
+    const std::string &Name = Proc->getName();
+    OS << "\n// Functional units for itineraries \"" << Name << "\"\n"
+       << "namespace " << Name << "FU {\n";
+
+    for (unsigned j = 0, FUN = FUs.size(); j < FUN; ++j)
+      OS << "  const unsigned " << FUs[j]->getName()
+         << " = 1 << " << j << ";\n";
+
+    OS << "}\n";
+  }
+
+  // Begin stages table
+  std::string StageTable = "\nstatic const llvm::InstrStage Stages[] = {\n";
+  StageTable += "  { 0, 0, 0, llvm::InstrStage::Required }, // No itinerary\n";
+        
+  // Begin operand cycle table
+  std::string OperandCycleTable = "static const unsigned OperandCycles[] = {\n";
+  OperandCycleTable += "  0, // No itinerary\n";
+        
+  unsigned StageCount = 1, OperandCycleCount = 1;
+  unsigned ItinStageEnum = 1, ItinOperandCycleEnum = 1;
+  std::map<std::string, unsigned> ItinStageMap, ItinOperandCycleMap;
+  for (unsigned i = 0, N = ProcItinList.size(); i < N; i++) {
+    // Next record
+    Record *Proc = ProcItinList[i];
+    
+    // Get processor itinerary name
+    const std::string &Name = Proc->getName();
+    
+    // Skip default
+    if (Name == "NoItineraries") continue;
+    
+    // Create and expand processor itinerary to cover all itinerary classes
+    std::vector<InstrItinerary> ItinList;
+    ItinList.resize(NItinClasses);
+    
+    // Get itinerary data list
+    std::vector<Record*> ItinDataList = Proc->getValueAsListOfDefs("IID");
+    
+    // For each itinerary data
+    for (unsigned j = 0, M = ItinDataList.size(); j < M; j++) {
+      // Next itinerary data
+      Record *ItinData = ItinDataList[j];
+      
+      // Get string and stage count
+      std::string ItinStageString;
+      unsigned NStages;
+      FormItineraryStageString(Name, ItinData, ItinStageString, NStages);
+
+      // Get string and operand cycle count
+      std::string ItinOperandCycleString;
+      unsigned NOperandCycles;
+      FormItineraryOperandCycleString(ItinData, ItinOperandCycleString,
+                                      NOperandCycles);
+
+      // Check to see if stage already exists and create if it doesn't
+      unsigned FindStage = 0;
+      if (NStages > 0) {
+        FindStage = ItinStageMap[ItinStageString];
+        if (FindStage == 0) {
+          // Emit as { cycles, u1 | u2 | ... | un, timeinc }, // index
+          StageTable += ItinStageString + ", // " + itostr(ItinStageEnum) + "\n";
+          // Record Itin class number.
+          ItinStageMap[ItinStageString] = FindStage = StageCount;
+          StageCount += NStages;
+          ItinStageEnum++;
+        }
+      }
+      
+      // Check to see if operand cycle already exists and create if it doesn't
+      unsigned FindOperandCycle = 0;
+      if (NOperandCycles > 0) {
+        FindOperandCycle = ItinOperandCycleMap[ItinOperandCycleString];
+        if (FindOperandCycle == 0) {
+          // Emit as  cycle, // index
+          OperandCycleTable += ItinOperandCycleString + ", // " + 
+            itostr(ItinOperandCycleEnum) + "\n";
+          // Record Itin class number.
+          ItinOperandCycleMap[ItinOperandCycleString] = 
+            FindOperandCycle = OperandCycleCount;
+          OperandCycleCount += NOperandCycles;
+          ItinOperandCycleEnum++;
+        }
+      }
+      
+      // Set up itinerary as location and location + stage count
+      InstrItinerary Intinerary = { FindStage, FindStage + NStages,
+                                    FindOperandCycle, FindOperandCycle + NOperandCycles};
+
+      // Locate where to inject into processor itinerary table
+      const std::string &Name = ItinData->getValueAsDef("TheClass")->getName();
+      unsigned Find = ItinClassesMap[Name];
+      
+      // Inject - empty slots will be 0, 0
+      ItinList[Find] = Intinerary;
+    }
+    
+    // Add process itinerary to list
+    ProcList.push_back(ItinList);
+  }
+  
+  // Closing stage
+  StageTable += "  { 0, 0, 0, llvm::InstrStage::Required } // End itinerary\n";
+  StageTable += "};\n";
+
+  // Closing operand cycles
+  OperandCycleTable += "  0 // End itinerary\n";
+  OperandCycleTable += "};\n";
+
+  // Emit tables.
+  OS << StageTable;
+  OS << OperandCycleTable;
+  
+  // Emit size of tables
+  OS<<"\nenum {\n";
+  OS<<"  StagesSize = sizeof(Stages)/sizeof(llvm::InstrStage),\n";
+  OS<<"  OperandCyclesSize = sizeof(OperandCycles)/sizeof(unsigned)\n";
+  OS<<"};\n";
+}
+
+//
+// EmitProcessorData - Generate data for processor itineraries.
+//
+void SubtargetEmitter::EmitProcessorData(raw_ostream &OS,
+      std::vector<std::vector<InstrItinerary> > &ProcList) {
+  // Get an iterator for processor itinerary stages
+  std::vector<std::vector<InstrItinerary> >::iterator
+      ProcListIter = ProcList.begin();
+  
+  // For each processor itinerary
+  std::vector<Record*> Itins =
+                       Records.getAllDerivedDefinitions("ProcessorItineraries");
+  for (unsigned i = 0, N = Itins.size(); i < N; i++) {
+    // Next record
+    Record *Itin = Itins[i];
+
+    // Get processor itinerary name
+    const std::string &Name = Itin->getName();
+    
+    // Skip default
+    if (Name == "NoItineraries") continue;
+
+    // Begin processor itinerary table
+    OS << "\n";
+    OS << "static const llvm::InstrItinerary " << Name << "[] = {\n";
+    
+    // For each itinerary class
+    std::vector<InstrItinerary> &ItinList = *ProcListIter++;
+    for (unsigned j = 0, M = ItinList.size(); j < M; ++j) {
+      InstrItinerary &Intinerary = ItinList[j];
+      
+      // Emit in the form of 
+      // { firstStage, lastStage, firstCycle, lastCycle } // index
+      if (Intinerary.FirstStage == 0) {
+        OS << "  { 0, 0, 0, 0 }";
+      } else {
+        OS << "  { " << Intinerary.FirstStage << ", " << 
+          Intinerary.LastStage << ", " << 
+          Intinerary.FirstOperandCycle << ", " << 
+          Intinerary.LastOperandCycle << " }";
+      }
+      
+      OS << ", // " << j << "\n";
+    }
+    
+    // End processor itinerary table
+    OS << "  { ~0U, ~0U, ~0U, ~0U } // end marker\n";
+    OS << "};\n";
+  }
+}
+
+//
+// EmitProcessorLookup - generate cpu name to itinerary lookup table.
+//
+void SubtargetEmitter::EmitProcessorLookup(raw_ostream &OS) {
+  // Gather and sort processor information
+  std::vector<Record*> ProcessorList =
+                          Records.getAllDerivedDefinitions("Processor");
+  std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
+
+  // Begin processor table
+  OS << "\n";
+  OS << "// Sorted (by key) array of itineraries for CPU subtype.\n"
+     << "static const llvm::SubtargetInfoKV ProcItinKV[] = {\n";
+     
+  // For each processor
+  for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
+    // Next processor
+    Record *Processor = ProcessorList[i];
+
+    const std::string &Name = Processor->getValueAsString("Name");
+    const std::string &ProcItin =
+      Processor->getValueAsDef("ProcItin")->getName();
+    
+    // Emit as { "cpu", procinit },
+    OS << "  { "
+       << "\"" << Name << "\", "
+       << "(void *)&" << ProcItin;
+        
+    OS << " }";
+    
+    // Depending on ''if more in the list'' emit comma
+    if (++i < N) OS << ",";
+    
+    OS << "\n";
+  }
+  
+  // End processor table
+  OS << "};\n";
+
+  // Emit size of table
+  OS<<"\nenum {\n";
+  OS<<"  ProcItinKVSize = sizeof(ProcItinKV)/"
+                            "sizeof(llvm::SubtargetInfoKV)\n";
+  OS<<"};\n";
+}
+
+//
+// EmitData - Emits all stages and itineries, folding common patterns.
+//
+void SubtargetEmitter::EmitData(raw_ostream &OS) {
+  std::map<std::string, unsigned> ItinClassesMap;
+  std::vector<std::vector<InstrItinerary> > ProcList;
+  
+  // Enumerate all the itinerary classes
+  unsigned NItinClasses = CollectAllItinClasses(OS, ItinClassesMap);
+  // Make sure the rest is worth the effort
+  HasItineraries = NItinClasses != 1;   // Ignore NoItinerary.
+  
+  if (HasItineraries) {
+    // Emit the stage data
+    EmitStageAndOperandCycleData(OS, NItinClasses, ItinClassesMap, ProcList);
+    // Emit the processor itinerary data
+    EmitProcessorData(OS, ProcList);
+    // Emit the processor lookup data
+    EmitProcessorLookup(OS);
+  }
+}
+
+//
+// ParseFeaturesFunction - Produces a subtarget specific function for parsing
+// the subtarget features string.
+//
+void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) {
+  std::vector<Record*> Features =
+                       Records.getAllDerivedDefinitions("SubtargetFeature");
+  std::sort(Features.begin(), Features.end(), LessRecord());
+
+  OS << "// ParseSubtargetFeatures - Parses features string setting specified\n" 
+     << "// subtarget options.\n" 
+     << "std::string llvm::";
+  OS << Target;
+  OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n"
+     << "                                  const std::string &CPU) {\n"
+     << "  DEBUG(dbgs() << \"\\nFeatures:\" << FS);\n"
+     << "  DEBUG(dbgs() << \"\\nCPU:\" << CPU);\n"
+     << "  SubtargetFeatures Features(FS);\n"
+     << "  Features.setCPUIfNone(CPU);\n"
+     << "  uint32_t Bits =  Features.getBits(SubTypeKV, SubTypeKVSize,\n"
+     << "                                    FeatureKV, FeatureKVSize);\n";
+
+  for (unsigned i = 0; i < Features.size(); i++) {
+    // Next record
+    Record *R = Features[i];
+    const std::string &Instance = R->getName();
+    const std::string &Value = R->getValueAsString("Value");
+    const std::string &Attribute = R->getValueAsString("Attribute");
+
+    if (Value=="true" || Value=="false")
+      OS << "  if ((Bits & " << Instance << ") != 0) "
+         << Attribute << " = " << Value << ";\n";
+    else
+      OS << "  if ((Bits & " << Instance << ") != 0 && " << Attribute << 
+            " < " << Value << ") " << Attribute << " = " << Value << ";\n";
+  }
+
+  if (HasItineraries) {
+    OS << "\n"
+       << "  InstrItinerary *Itinerary = (InstrItinerary *)"
+       <<              "Features.getInfo(ProcItinKV, ProcItinKVSize);\n"
+       << "  InstrItins = InstrItineraryData(Stages, OperandCycles, Itinerary);\n";
+  }
+
+  OS << "  return Features.getCPU();\n"
+     << "}\n";
+}
+
+//
+// SubtargetEmitter::run - Main subtarget enumeration emitter.
+//
+void SubtargetEmitter::run(raw_ostream &OS) {
+  Target = CodeGenTarget().getName();
+
+  EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
+
+  OS << "#include \"llvm/Support/Debug.h\"\n";
+  OS << "#include \"llvm/Support/raw_ostream.h\"\n";
+  OS << "#include \"llvm/Target/SubtargetFeature.h\"\n";
+  OS << "#include \"llvm/Target/TargetInstrItineraries.h\"\n\n";
+
+//  Enumeration(OS, "FuncUnit", true);
+//  OS<<"\n";
+//  Enumeration(OS, "InstrItinClass", false);
+//  OS<<"\n";
+  Enumeration(OS, "SubtargetFeature", true);
+  OS<<"\n";
+  FeatureKeyValues(OS);
+  OS<<"\n";
+  CPUKeyValues(OS);
+  OS<<"\n";
+  EmitData(OS);
+  OS<<"\n";
+  ParseFeaturesFunction(OS);
+}
diff --git a/src/LLVM/utils/TableGen/SubtargetEmitter.h b/src/LLVM/utils/TableGen/SubtargetEmitter.h
new file mode 100644
index 0000000..f43a443
--- /dev/null
+++ b/src/LLVM/utils/TableGen/SubtargetEmitter.h
@@ -0,0 +1,65 @@
+//===- SubtargetEmitter.h - Generate subtarget enumerations -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend emits subtarget enumerations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUBTARGET_EMITTER_H
+#define SUBTARGET_EMITTER_H
+
+#include "TableGenBackend.h"
+#include "llvm/Target/TargetInstrItineraries.h"
+#include <vector>
+#include <map>
+#include <string>
+
+
+namespace llvm {
+
+class SubtargetEmitter : public TableGenBackend {
+  
+  RecordKeeper &Records;
+  std::string Target;
+  bool HasItineraries;
+  
+  void Enumeration(raw_ostream &OS, const char *ClassName, bool isBits);
+  void FeatureKeyValues(raw_ostream &OS);
+  void CPUKeyValues(raw_ostream &OS);
+  unsigned CollectAllItinClasses(raw_ostream &OS,
+                               std::map<std::string, unsigned> &ItinClassesMap);
+  void FormItineraryStageString(const std::string &Names,
+                                Record *ItinData, std::string &ItinString,
+                                unsigned &NStages);
+  void FormItineraryOperandCycleString(Record *ItinData, std::string &ItinString,
+                                       unsigned &NOperandCycles);
+  void EmitStageAndOperandCycleData(raw_ostream &OS, unsigned NItinClasses,
+                     std::map<std::string, unsigned> &ItinClassesMap,
+                     std::vector<std::vector<InstrItinerary> > &ProcList);
+  void EmitProcessorData(raw_ostream &OS,
+                       std::vector<std::vector<InstrItinerary> > &ProcList);
+  void EmitProcessorLookup(raw_ostream &OS);
+  void EmitData(raw_ostream &OS);
+  void ParseFeaturesFunction(raw_ostream &OS);
+  
+public:
+  SubtargetEmitter(RecordKeeper &R) : Records(R), HasItineraries(false) {}
+
+  // run - Output the subtarget enumerations, returning true on failure.
+  void run(raw_ostream &o);
+
+};
+
+
+} // End llvm namespace
+
+#endif
+
+
+
diff --git a/src/LLVM/utils/TableGen/TGLexer.cpp b/src/LLVM/utils/TableGen/TGLexer.cpp
new file mode 100644
index 0000000..2c7becc
--- /dev/null
+++ b/src/LLVM/utils/TableGen/TGLexer.cpp
@@ -0,0 +1,450 @@
+//===- TGLexer.cpp - Lexer for TableGen -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implement the Lexer for TableGen.
+//
+//===----------------------------------------------------------------------===//
+
+#include "TGLexer.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Config/config.h"
+#include <cctype>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <cerrno>
+using namespace llvm;
+
+TGLexer::TGLexer(SourceMgr &SM) : SrcMgr(SM) {
+  CurBuffer = 0;
+  CurBuf = SrcMgr.getMemoryBuffer(CurBuffer);
+  CurPtr = CurBuf->getBufferStart();
+  TokStart = 0;
+}
+
+SMLoc TGLexer::getLoc() const {
+  return SMLoc::getFromPointer(TokStart);
+}
+
+
+/// ReturnError - Set the error to the specified string at the specified
+/// location.  This is defined to always return tgtok::Error.
+tgtok::TokKind TGLexer::ReturnError(const char *Loc, const std::string &Msg) {
+  PrintError(Loc, Msg);
+  return tgtok::Error;
+}
+
+
+void TGLexer::PrintError(const char *Loc, const std::string &Msg) const {
+  SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), Msg, "error");
+}
+
+void TGLexer::PrintError(SMLoc Loc, const std::string &Msg) const {
+  SrcMgr.PrintMessage(Loc, Msg, "error");
+}
+
+
+int TGLexer::getNextChar() {
+  char CurChar = *CurPtr++;
+  switch (CurChar) {
+  default:
+    return (unsigned char)CurChar;
+  case 0: {
+    // A nul character in the stream is either the end of the current buffer or
+    // a random nul in the file.  Disambiguate that here.
+    if (CurPtr-1 != CurBuf->getBufferEnd())
+      return 0;  // Just whitespace.
+    
+    // If this is the end of an included file, pop the parent file off the
+    // include stack.
+    SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
+    if (ParentIncludeLoc != SMLoc()) {
+      CurBuffer = SrcMgr.FindBufferContainingLoc(ParentIncludeLoc);
+      CurBuf = SrcMgr.getMemoryBuffer(CurBuffer);
+      CurPtr = ParentIncludeLoc.getPointer();
+      return getNextChar();
+    }
+    
+    // Otherwise, return end of file.
+    --CurPtr;  // Another call to lex will return EOF again.  
+    return EOF;
+  }
+  case '\n':
+  case '\r':
+    // Handle the newline character by ignoring it and incrementing the line
+    // count.  However, be careful about 'dos style' files with \n\r in them.
+    // Only treat a \n\r or \r\n as a single line.
+    if ((*CurPtr == '\n' || (*CurPtr == '\r')) &&
+        *CurPtr != CurChar)
+      ++CurPtr;  // Eat the two char newline sequence.
+    return '\n';
+  }  
+}
+
+tgtok::TokKind TGLexer::LexToken() {
+  TokStart = CurPtr;
+  // This always consumes at least one character.
+  int CurChar = getNextChar();
+
+  switch (CurChar) {
+  default:
+    // Handle letters: [a-zA-Z_]
+    if (isalpha(CurChar) || CurChar == '_' || CurChar == '#')
+      return LexIdentifier();
+      
+    // Unknown character, emit an error.
+    return ReturnError(TokStart, "Unexpected character");
+  case EOF: return tgtok::Eof;
+  case ':': return tgtok::colon;
+  case ';': return tgtok::semi;
+  case '.': return tgtok::period;
+  case ',': return tgtok::comma;
+  case '<': return tgtok::less;
+  case '>': return tgtok::greater;
+  case ']': return tgtok::r_square;
+  case '{': return tgtok::l_brace;
+  case '}': return tgtok::r_brace;
+  case '(': return tgtok::l_paren;
+  case ')': return tgtok::r_paren;
+  case '=': return tgtok::equal;
+  case '?': return tgtok::question;
+      
+  case 0:
+  case ' ':
+  case '\t':
+  case '\n':
+  case '\r':
+    // Ignore whitespace.
+    return LexToken();
+  case '/':
+    // If this is the start of a // comment, skip until the end of the line or
+    // the end of the buffer.
+    if (*CurPtr == '/')
+      SkipBCPLComment();
+    else if (*CurPtr == '*') {
+      if (SkipCComment())
+        return tgtok::Error;
+    } else // Otherwise, this is an error.
+      return ReturnError(TokStart, "Unexpected character");
+    return LexToken();
+  case '-': case '+':
+  case '0': case '1': case '2': case '3': case '4': case '5': case '6':
+  case '7': case '8': case '9':  
+    return LexNumber();
+  case '"': return LexString();
+  case '$': return LexVarName();
+  case '[': return LexBracket();
+  case '!': return LexExclaim();
+  }
+}
+
+/// LexString - Lex "[^"]*"
+tgtok::TokKind TGLexer::LexString() {
+  const char *StrStart = CurPtr;
+  
+  CurStrVal = "";
+  
+  while (*CurPtr != '"') {
+    // If we hit the end of the buffer, report an error.
+    if (*CurPtr == 0 && CurPtr == CurBuf->getBufferEnd())
+      return ReturnError(StrStart, "End of file in string literal");
+    
+    if (*CurPtr == '\n' || *CurPtr == '\r')
+      return ReturnError(StrStart, "End of line in string literal");
+    
+    if (*CurPtr != '\\') {
+      CurStrVal += *CurPtr++;
+      continue;
+    }
+
+    ++CurPtr;
+    
+    switch (*CurPtr) {
+    case '\\': case '\'': case '"':
+      // These turn into their literal character.
+      CurStrVal += *CurPtr++;
+      break;
+    case 't':
+      CurStrVal += '\t';
+      ++CurPtr;
+      break;
+    case 'n':
+      CurStrVal += '\n';
+      ++CurPtr;
+      break;
+        
+    case '\n':
+    case '\r':
+      return ReturnError(CurPtr, "escaped newlines not supported in tblgen");
+
+    // If we hit the end of the buffer, report an error.
+    case '\0':
+      if (CurPtr == CurBuf->getBufferEnd())
+        return ReturnError(StrStart, "End of file in string literal");
+      // FALL THROUGH
+    default:
+      return ReturnError(CurPtr, "invalid escape in string literal");
+    }
+  }
+  
+  ++CurPtr;
+  return tgtok::StrVal;
+}
+
+tgtok::TokKind TGLexer::LexVarName() {
+  if (!isalpha(CurPtr[0]) && CurPtr[0] != '_')
+    return ReturnError(TokStart, "Invalid variable name");
+  
+  // Otherwise, we're ok, consume the rest of the characters.
+  const char *VarNameStart = CurPtr++;
+  
+  while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_')
+    ++CurPtr;
+
+  CurStrVal.assign(VarNameStart, CurPtr);
+  return tgtok::VarName;
+}
+
+
+tgtok::TokKind TGLexer::LexIdentifier() {
+  // The first letter is [a-zA-Z_].
+  const char *IdentStart = TokStart;
+  
+  // Match the rest of the identifier regex: [0-9a-zA-Z_]*
+  while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_'
+         || *CurPtr == '#') {
+    // If this contains a '#', make sure it's value
+    if (*CurPtr == '#') {
+      if (strncmp(CurPtr, "#NAME#", 6) != 0) {
+        return tgtok::Error;
+      }
+      CurPtr += 6;
+    }
+    else {
+      ++CurPtr;
+    }
+  }
+  
+  
+  // Check to see if this identifier is a keyword.
+  unsigned Len = CurPtr-IdentStart;
+  
+  if (Len == 3 && !memcmp(IdentStart, "int", 3)) return tgtok::Int;
+  if (Len == 3 && !memcmp(IdentStart, "bit", 3)) return tgtok::Bit;
+  if (Len == 4 && !memcmp(IdentStart, "bits", 4)) return tgtok::Bits;
+  if (Len == 6 && !memcmp(IdentStart, "string", 6)) return tgtok::String;
+  if (Len == 4 && !memcmp(IdentStart, "list", 4)) return tgtok::List;
+  if (Len == 4 && !memcmp(IdentStart, "code", 4)) return tgtok::Code;
+  if (Len == 3 && !memcmp(IdentStart, "dag", 3)) return tgtok::Dag;
+  
+  if (Len == 5 && !memcmp(IdentStart, "class", 5)) return tgtok::Class;
+  if (Len == 3 && !memcmp(IdentStart, "def", 3)) return tgtok::Def;
+  if (Len == 4 && !memcmp(IdentStart, "defm", 4)) return tgtok::Defm;
+  if (Len == 10 && !memcmp(IdentStart, "multiclass", 10))
+    return tgtok::MultiClass;
+  if (Len == 5 && !memcmp(IdentStart, "field", 5)) return tgtok::Field;
+  if (Len == 3 && !memcmp(IdentStart, "let", 3)) return tgtok::Let;
+  if (Len == 2 && !memcmp(IdentStart, "in", 2)) return tgtok::In;
+  
+  if (Len == 7 && !memcmp(IdentStart, "include", 7)) {
+    if (LexInclude()) return tgtok::Error;
+    return Lex();
+  }
+    
+  CurStrVal.assign(IdentStart, CurPtr);
+  return tgtok::Id;
+}
+
+/// LexInclude - We just read the "include" token.  Get the string token that
+/// comes next and enter the include.
+bool TGLexer::LexInclude() {
+  // The token after the include must be a string.
+  tgtok::TokKind Tok = LexToken();
+  if (Tok == tgtok::Error) return true;
+  if (Tok != tgtok::StrVal) {
+    PrintError(getLoc(), "Expected filename after include");
+    return true;
+  }
+
+  // Get the string.
+  std::string Filename = CurStrVal;
+
+  
+  CurBuffer = SrcMgr.AddIncludeFile(Filename, SMLoc::getFromPointer(CurPtr));
+  if (CurBuffer == -1) {
+    PrintError(getLoc(), "Could not find include file '" + Filename + "'");
+    return true;
+  }
+  
+  // Save the line number and lex buffer of the includer.
+  CurBuf = SrcMgr.getMemoryBuffer(CurBuffer);
+  CurPtr = CurBuf->getBufferStart();
+  return false;
+}
+
+void TGLexer::SkipBCPLComment() {
+  ++CurPtr;  // skip the second slash.
+  while (1) {
+    switch (*CurPtr) {
+    case '\n':
+    case '\r':
+      return;  // Newline is end of comment.
+    case 0:
+      // If this is the end of the buffer, end the comment.
+      if (CurPtr == CurBuf->getBufferEnd())
+        return;
+      break;
+    }
+    // Otherwise, skip the character.
+    ++CurPtr;
+  }
+}
+
+/// SkipCComment - This skips C-style /**/ comments.  The only difference from C
+/// is that we allow nesting.
+bool TGLexer::SkipCComment() {
+  ++CurPtr;  // skip the star.
+  unsigned CommentDepth = 1;
+  
+  while (1) {
+    int CurChar = getNextChar();
+    switch (CurChar) {
+    case EOF:
+      PrintError(TokStart, "Unterminated comment!");
+      return true;
+    case '*':
+      // End of the comment?
+      if (CurPtr[0] != '/') break;
+      
+      ++CurPtr;   // End the */.
+      if (--CommentDepth == 0)
+        return false;
+      break;
+    case '/':
+      // Start of a nested comment?
+      if (CurPtr[0] != '*') break;
+      ++CurPtr;
+      ++CommentDepth;
+      break;
+    }
+  }
+}
+
+/// LexNumber - Lex:
+///    [-+]?[0-9]+
+///    0x[0-9a-fA-F]+
+///    0b[01]+
+tgtok::TokKind TGLexer::LexNumber() {
+  if (CurPtr[-1] == '0') {
+    if (CurPtr[0] == 'x') {
+      ++CurPtr;
+      const char *NumStart = CurPtr;
+      while (isxdigit(CurPtr[0]))
+        ++CurPtr;
+      
+      // Requires at least one hex digit.
+      if (CurPtr == NumStart)
+        return ReturnError(TokStart, "Invalid hexadecimal number");
+
+      errno = 0;
+      CurIntVal = strtoll(NumStart, 0, 16);
+      if (errno == EINVAL)
+        return ReturnError(TokStart, "Invalid hexadecimal number");
+      if (errno == ERANGE) {
+        errno = 0;
+        CurIntVal = (int64_t)strtoull(NumStart, 0, 16);
+        if (errno == EINVAL)
+          return ReturnError(TokStart, "Invalid hexadecimal number");
+        if (errno == ERANGE)
+          return ReturnError(TokStart, "Hexadecimal number out of range");
+      }
+      return tgtok::IntVal;
+    } else if (CurPtr[0] == 'b') {
+      ++CurPtr;
+      const char *NumStart = CurPtr;
+      while (CurPtr[0] == '0' || CurPtr[0] == '1')
+        ++CurPtr;
+
+      // Requires at least one binary digit.
+      if (CurPtr == NumStart)
+        return ReturnError(CurPtr-2, "Invalid binary number");
+      CurIntVal = strtoll(NumStart, 0, 2);
+      return tgtok::IntVal;
+    }
+  }
+
+  // Check for a sign without a digit.
+  if (!isdigit(CurPtr[0])) {
+    if (CurPtr[-1] == '-')
+      return tgtok::minus;
+    else if (CurPtr[-1] == '+')
+      return tgtok::plus;
+  }
+  
+  while (isdigit(CurPtr[0]))
+    ++CurPtr;
+  CurIntVal = strtoll(TokStart, 0, 10);
+  return tgtok::IntVal;
+}
+
+/// LexBracket - We just read '['.  If this is a code block, return it,
+/// otherwise return the bracket.  Match: '[' and '[{ ( [^}]+ | }[^]] )* }]'
+tgtok::TokKind TGLexer::LexBracket() {
+  if (CurPtr[0] != '{')
+    return tgtok::l_square;
+  ++CurPtr;
+  const char *CodeStart = CurPtr;
+  while (1) {
+    int Char = getNextChar();
+    if (Char == EOF) break;
+    
+    if (Char != '}') continue;
+    
+    Char = getNextChar();
+    if (Char == EOF) break;
+    if (Char == ']') {
+      CurStrVal.assign(CodeStart, CurPtr-2);
+      return tgtok::CodeFragment;
+    }
+  }
+  
+  return ReturnError(CodeStart-2, "Unterminated Code Block");
+}
+
+/// LexExclaim - Lex '!' and '![a-zA-Z]+'.
+tgtok::TokKind TGLexer::LexExclaim() {
+  if (!isalpha(*CurPtr))
+    return ReturnError(CurPtr-1, "Invalid \"!operator\"");
+  
+  const char *Start = CurPtr++;
+  while (isalpha(*CurPtr))
+    ++CurPtr;
+  
+  // Check to see which operator this is.
+  unsigned Len = CurPtr-Start;
+  
+  if (Len == 3  && !memcmp(Start, "con", 3)) return tgtok::XConcat;
+  if (Len == 3  && !memcmp(Start, "sra", 3)) return tgtok::XSRA;
+  if (Len == 3  && !memcmp(Start, "srl", 3)) return tgtok::XSRL;
+  if (Len == 3  && !memcmp(Start, "shl", 3)) return tgtok::XSHL;
+  if (Len == 2  && !memcmp(Start, "eq", 2)) return tgtok::XEq;
+  if (Len == 9  && !memcmp(Start, "strconcat", 9))   return tgtok::XStrConcat;
+  if (Len == 10 && !memcmp(Start, "nameconcat", 10)) return tgtok::XNameConcat;
+  if (Len == 5 && !memcmp(Start, "subst", 5)) return tgtok::XSubst;
+  if (Len == 7 && !memcmp(Start, "foreach", 7)) return tgtok::XForEach;
+  if (Len == 4 && !memcmp(Start, "cast", 4)) return tgtok::XCast;
+  if (Len == 3 && !memcmp(Start, "car", 3)) return tgtok::XCar;
+  if (Len == 3 && !memcmp(Start, "cdr", 3)) return tgtok::XCdr;
+  if (Len == 4 && !memcmp(Start, "null", 4)) return tgtok::XNull;
+  if (Len == 2 && !memcmp(Start, "if", 2)) return tgtok::XIf;
+
+  return ReturnError(Start-1, "Unknown operator");
+}
+
diff --git a/src/LLVM/utils/TableGen/TGLexer.h b/src/LLVM/utils/TableGen/TGLexer.h
new file mode 100644
index 0000000..835f351
--- /dev/null
+++ b/src/LLVM/utils/TableGen/TGLexer.h
@@ -0,0 +1,121 @@
+//===- TGLexer.h - Lexer for TableGen Files ---------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class represents the Lexer for tablegen files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TGLEXER_H
+#define TGLEXER_H
+
+#include "llvm/System/DataTypes.h"
+#include <vector>
+#include <string>
+#include <cassert>
+
+namespace llvm {
+class MemoryBuffer;
+class SourceMgr;
+class SMLoc;
+  
+namespace tgtok {
+  enum TokKind {
+    // Markers
+    Eof, Error,
+    
+    // Tokens with no info.
+    minus, plus,        // - +
+    l_square, r_square, // [ ]
+    l_brace, r_brace,   // { }
+    l_paren, r_paren,   // ( )
+    less, greater,      // < >
+    colon, semi,        // ; :
+    comma, period,      // , .
+    equal, question,    // = ?
+    
+    // Keywords.
+    Bit, Bits, Class, Code, Dag, Def, Defm, Field, In, Int, Let, List,
+    MultiClass, String,
+    
+    // !keywords.
+    XConcat, XSRA, XSRL, XSHL, XStrConcat, XNameConcat, XCast, XSubst,
+    XForEach, XCar, XCdr, XNull, XIf, XEq,
+
+    // Integer value.
+    IntVal,
+    
+    // String valued tokens.
+    Id, StrVal, VarName, CodeFragment
+  };
+}
+
+/// TGLexer - TableGen Lexer class.
+class TGLexer {
+  SourceMgr &SrcMgr;
+  
+  const char *CurPtr;
+  const MemoryBuffer *CurBuf;
+
+  // Information about the current token.
+  const char *TokStart;
+  tgtok::TokKind CurCode;
+  std::string CurStrVal;  // This is valid for ID, STRVAL, VARNAME, CODEFRAGMENT
+  int64_t CurIntVal;      // This is valid for INTVAL.
+
+  /// CurBuffer - This is the current buffer index we're lexing from as managed
+  /// by the SourceMgr object.
+  int CurBuffer;
+  
+public:
+  TGLexer(SourceMgr &SrcMgr);
+  ~TGLexer() {}
+  
+  tgtok::TokKind Lex() {
+    return CurCode = LexToken();
+  }
+  
+  tgtok::TokKind getCode() const { return CurCode; }
+
+  const std::string &getCurStrVal() const {
+    assert((CurCode == tgtok::Id || CurCode == tgtok::StrVal || 
+            CurCode == tgtok::VarName || CurCode == tgtok::CodeFragment) &&
+           "This token doesn't have a string value");
+    return CurStrVal;
+  }
+  int64_t getCurIntVal() const {
+    assert(CurCode == tgtok::IntVal && "This token isn't an integer");
+    return CurIntVal;
+  }
+
+  SMLoc getLoc() const;
+
+  void PrintError(const char *Loc, const std::string &Msg) const;
+  void PrintError(SMLoc Loc, const std::string &Msg) const;
+  
+private:
+  /// LexToken - Read the next token and return its code.
+  tgtok::TokKind LexToken();
+  
+  tgtok::TokKind ReturnError(const char *Loc, const std::string &Msg);
+  
+  int getNextChar();
+  void SkipBCPLComment();
+  bool SkipCComment();
+  tgtok::TokKind LexIdentifier();
+  bool LexInclude();
+  tgtok::TokKind LexString();
+  tgtok::TokKind LexVarName();
+  tgtok::TokKind LexNumber();
+  tgtok::TokKind LexBracket();
+  tgtok::TokKind LexExclaim();
+};
+  
+} // end namespace llvm
+
+#endif
diff --git a/src/LLVM/utils/TableGen/TGParser.cpp b/src/LLVM/utils/TableGen/TGParser.cpp
new file mode 100644
index 0000000..f81aabe
--- /dev/null
+++ b/src/LLVM/utils/TableGen/TGParser.cpp
@@ -0,0 +1,2123 @@
+//===- TGParser.cpp - Parser for TableGen Files ---------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implement the Parser for TableGen.
+//
+//===----------------------------------------------------------------------===//
+
+#include "TGParser.h"
+#include "Record.h"
+#include "llvm/ADT/StringExtras.h"
+#include <algorithm>
+#include <sstream>
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// Support Code for the Semantic Actions.
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+struct SubClassReference {
+  SMLoc RefLoc;
+  Record *Rec;
+  std::vector<Init*> TemplateArgs;
+  SubClassReference() : Rec(0) {}
+
+  bool isInvalid() const { return Rec == 0; }
+};
+
+struct SubMultiClassReference {
+  SMLoc RefLoc;
+  MultiClass *MC;
+  std::vector<Init*> TemplateArgs;
+  SubMultiClassReference() : MC(0) {}
+
+  bool isInvalid() const { return MC == 0; }
+  void dump() const;
+};
+
+void SubMultiClassReference::dump() const {
+  errs() << "Multiclass:\n";
+
+  MC->dump();
+
+  errs() << "Template args:\n";
+  for (std::vector<Init *>::const_iterator i = TemplateArgs.begin(),
+         iend = TemplateArgs.end();
+       i != iend;
+       ++i) {
+    (*i)->dump();
+  }
+}
+
+} // end namespace llvm
+
+bool TGParser::AddValue(Record *CurRec, SMLoc Loc, const RecordVal &RV) {
+  if (CurRec == 0)
+    CurRec = &CurMultiClass->Rec;
+
+  if (RecordVal *ERV = CurRec->getValue(RV.getName())) {
+    // The value already exists in the class, treat this as a set.
+    if (ERV->setValue(RV.getValue()))
+      return Error(Loc, "New definition of '" + RV.getName() + "' of type '" +
+                   RV.getType()->getAsString() + "' is incompatible with " +
+                   "previous definition of type '" +
+                   ERV->getType()->getAsString() + "'");
+  } else {
+    CurRec->addValue(RV);
+  }
+  return false;
+}
+
+/// SetValue -
+/// Return true on error, false on success.
+bool TGParser::SetValue(Record *CurRec, SMLoc Loc, const std::string &ValName,
+                        const std::vector<unsigned> &BitList, Init *V) {
+  if (!V) return false;
+
+  if (CurRec == 0) CurRec = &CurMultiClass->Rec;
+
+  RecordVal *RV = CurRec->getValue(ValName);
+  if (RV == 0)
+    return Error(Loc, "Value '" + ValName + "' unknown!");
+
+  // Do not allow assignments like 'X = X'.  This will just cause infinite loops
+  // in the resolution machinery.
+  if (BitList.empty())
+    if (VarInit *VI = dynamic_cast<VarInit*>(V))
+      if (VI->getName() == ValName)
+        return false;
+
+  // If we are assigning to a subset of the bits in the value... then we must be
+  // assigning to a field of BitsRecTy, which must have a BitsInit
+  // initializer.
+  //
+  if (!BitList.empty()) {
+    BitsInit *CurVal = dynamic_cast<BitsInit*>(RV->getValue());
+    if (CurVal == 0)
+      return Error(Loc, "Value '" + ValName + "' is not a bits type");
+
+    // Convert the incoming value to a bits type of the appropriate size...
+    Init *BI = V->convertInitializerTo(new BitsRecTy(BitList.size()));
+    if (BI == 0) {
+      V->convertInitializerTo(new BitsRecTy(BitList.size()));
+      return Error(Loc, "Initializer is not compatible with bit range");
+    }
+
+    // We should have a BitsInit type now.
+    BitsInit *BInit = dynamic_cast<BitsInit*>(BI);
+    assert(BInit != 0);
+
+    BitsInit *NewVal = new BitsInit(CurVal->getNumBits());
+
+    // Loop over bits, assigning values as appropriate.
+    for (unsigned i = 0, e = BitList.size(); i != e; ++i) {
+      unsigned Bit = BitList[i];
+      if (NewVal->getBit(Bit))
+        return Error(Loc, "Cannot set bit #" + utostr(Bit) + " of value '" +
+                     ValName + "' more than once");
+      NewVal->setBit(Bit, BInit->getBit(i));
+    }
+
+    for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i)
+      if (NewVal->getBit(i) == 0)
+        NewVal->setBit(i, CurVal->getBit(i));
+
+    V = NewVal;
+  }
+
+  if (RV->setValue(V))
+   return Error(Loc, "Value '" + ValName + "' of type '" +
+                RV->getType()->getAsString() +
+                "' is incompatible with initializer '" + V->getAsString() +"'");
+  return false;
+}
+
+/// AddSubClass - Add SubClass as a subclass to CurRec, resolving its template
+/// args as SubClass's template arguments.
+bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) {
+  Record *SC = SubClass.Rec;
+  // Add all of the values in the subclass into the current class.
+  const std::vector<RecordVal> &Vals = SC->getValues();
+  for (unsigned i = 0, e = Vals.size(); i != e; ++i)
+    if (AddValue(CurRec, SubClass.RefLoc, Vals[i]))
+      return true;
+
+  const std::vector<std::string> &TArgs = SC->getTemplateArgs();
+
+  // Ensure that an appropriate number of template arguments are specified.
+  if (TArgs.size() < SubClass.TemplateArgs.size())
+    return Error(SubClass.RefLoc, "More template args specified than expected");
+
+  // Loop over all of the template arguments, setting them to the specified
+  // value or leaving them as the default if necessary.
+  for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
+    if (i < SubClass.TemplateArgs.size()) {
+      // If a value is specified for this template arg, set it now.
+      if (SetValue(CurRec, SubClass.RefLoc, TArgs[i], std::vector<unsigned>(),
+                   SubClass.TemplateArgs[i]))
+        return true;
+
+      // Resolve it next.
+      CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i]));
+
+      // Now remove it.
+      CurRec->removeValue(TArgs[i]);
+
+    } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
+      return Error(SubClass.RefLoc,"Value not specified for template argument #"
+                   + utostr(i) + " (" + TArgs[i] + ") of subclass '" +
+                   SC->getName() + "'!");
+    }
+  }
+
+  // Since everything went well, we can now set the "superclass" list for the
+  // current record.
+  const std::vector<Record*> &SCs = SC->getSuperClasses();
+  for (unsigned i = 0, e = SCs.size(); i != e; ++i) {
+    if (CurRec->isSubClassOf(SCs[i]))
+      return Error(SubClass.RefLoc,
+                   "Already subclass of '" + SCs[i]->getName() + "'!\n");
+    CurRec->addSuperClass(SCs[i]);
+  }
+
+  if (CurRec->isSubClassOf(SC))
+    return Error(SubClass.RefLoc,
+                 "Already subclass of '" + SC->getName() + "'!\n");
+  CurRec->addSuperClass(SC);
+  return false;
+}
+
+/// AddSubMultiClass - Add SubMultiClass as a subclass to
+/// CurMC, resolving its template args as SubMultiClass's
+/// template arguments.
+bool TGParser::AddSubMultiClass(MultiClass *CurMC,
+                                SubMultiClassReference &SubMultiClass) {
+  MultiClass *SMC = SubMultiClass.MC;
+  Record *CurRec = &CurMC->Rec;
+
+  const std::vector<RecordVal> &MCVals = CurRec->getValues();
+
+  // Add all of the values in the subclass into the current class.
+  const std::vector<RecordVal> &SMCVals = SMC->Rec.getValues();
+  for (unsigned i = 0, e = SMCVals.size(); i != e; ++i)
+    if (AddValue(CurRec, SubMultiClass.RefLoc, SMCVals[i]))
+      return true;
+
+  int newDefStart = CurMC->DefPrototypes.size();
+
+  // Add all of the defs in the subclass into the current multiclass.
+  for (MultiClass::RecordVector::const_iterator i = SMC->DefPrototypes.begin(),
+         iend = SMC->DefPrototypes.end();
+       i != iend;
+       ++i) {
+    // Clone the def and add it to the current multiclass
+    Record *NewDef = new Record(**i);
+
+    // Add all of the values in the superclass into the current def.
+    for (unsigned i = 0, e = MCVals.size(); i != e; ++i)
+      if (AddValue(NewDef, SubMultiClass.RefLoc, MCVals[i]))
+        return true;
+
+    CurMC->DefPrototypes.push_back(NewDef);
+  }
+
+  const std::vector<std::string> &SMCTArgs = SMC->Rec.getTemplateArgs();
+
+  // Ensure that an appropriate number of template arguments are
+  // specified.
+  if (SMCTArgs.size() < SubMultiClass.TemplateArgs.size())
+    return Error(SubMultiClass.RefLoc,
+                 "More template args specified than expected");
+
+  // Loop over all of the template arguments, setting them to the specified
+  // value or leaving them as the default if necessary.
+  for (unsigned i = 0, e = SMCTArgs.size(); i != e; ++i) {
+    if (i < SubMultiClass.TemplateArgs.size()) {
+      // If a value is specified for this template arg, set it in the
+      // superclass now.
+      if (SetValue(CurRec, SubMultiClass.RefLoc, SMCTArgs[i],
+                   std::vector<unsigned>(),
+                   SubMultiClass.TemplateArgs[i]))
+        return true;
+
+      // Resolve it next.
+      CurRec->resolveReferencesTo(CurRec->getValue(SMCTArgs[i]));
+
+      // Now remove it.
+      CurRec->removeValue(SMCTArgs[i]);
+
+      // If a value is specified for this template arg, set it in the
+      // new defs now.
+      for (MultiClass::RecordVector::iterator j =
+             CurMC->DefPrototypes.begin() + newDefStart,
+             jend = CurMC->DefPrototypes.end();
+           j != jend;
+           ++j) {
+        Record *Def = *j;
+
+        if (SetValue(Def, SubMultiClass.RefLoc, SMCTArgs[i],
+                     std::vector<unsigned>(),
+                     SubMultiClass.TemplateArgs[i]))
+          return true;
+
+        // Resolve it next.
+        Def->resolveReferencesTo(Def->getValue(SMCTArgs[i]));
+
+        // Now remove it
+        Def->removeValue(SMCTArgs[i]);
+      }
+    } else if (!CurRec->getValue(SMCTArgs[i])->getValue()->isComplete()) {
+      return Error(SubMultiClass.RefLoc,
+                   "Value not specified for template argument #"
+                   + utostr(i) + " (" + SMCTArgs[i] + ") of subclass '" +
+                   SMC->Rec.getName() + "'!");
+    }
+  }
+
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// Parser Code
+//===----------------------------------------------------------------------===//
+
+/// isObjectStart - Return true if this is a valid first token for an Object.
+static bool isObjectStart(tgtok::TokKind K) {
+  return K == tgtok::Class || K == tgtok::Def ||
+         K == tgtok::Defm || K == tgtok::Let || K == tgtok::MultiClass;
+}
+
+/// ParseObjectName - If an object name is specified, return it.  Otherwise,
+/// return an anonymous name.
+///   ObjectName ::= ID
+///   ObjectName ::= /*empty*/
+///
+std::string TGParser::ParseObjectName() {
+  if (Lex.getCode() == tgtok::Id) {
+    std::string Ret = Lex.getCurStrVal();
+    Lex.Lex();
+    return Ret;
+  }
+
+  static unsigned AnonCounter = 0;
+  return "anonymous."+utostr(AnonCounter++);
+}
+
+
+/// ParseClassID - Parse and resolve a reference to a class name.  This returns
+/// null on error.
+///
+///    ClassID ::= ID
+///
+Record *TGParser::ParseClassID() {
+  if (Lex.getCode() != tgtok::Id) {
+    TokError("expected name for ClassID");
+    return 0;
+  }
+
+  Record *Result = Records.getClass(Lex.getCurStrVal());
+  if (Result == 0)
+    TokError("Couldn't find class '" + Lex.getCurStrVal() + "'");
+
+  Lex.Lex();
+  return Result;
+}
+
+/// ParseMultiClassID - Parse and resolve a reference to a multiclass name.
+/// This returns null on error.
+///
+///    MultiClassID ::= ID
+///
+MultiClass *TGParser::ParseMultiClassID() {
+  if (Lex.getCode() != tgtok::Id) {
+    TokError("expected name for ClassID");
+    return 0;
+  }
+
+  MultiClass *Result = MultiClasses[Lex.getCurStrVal()];
+  if (Result == 0)
+    TokError("Couldn't find class '" + Lex.getCurStrVal() + "'");
+
+  Lex.Lex();
+  return Result;
+}
+
+Record *TGParser::ParseDefmID() {
+  if (Lex.getCode() != tgtok::Id) {
+    TokError("expected multiclass name");
+    return 0;
+  }
+
+  MultiClass *MC = MultiClasses[Lex.getCurStrVal()];
+  if (MC == 0) {
+    TokError("Couldn't find multiclass '" + Lex.getCurStrVal() + "'");
+    return 0;
+  }
+
+  Lex.Lex();
+  return &MC->Rec;
+}
+
+
+/// ParseSubClassReference - Parse a reference to a subclass or to a templated
+/// subclass.  This returns a SubClassRefTy with a null Record* on error.
+///
+///  SubClassRef ::= ClassID
+///  SubClassRef ::= ClassID '<' ValueList '>'
+///
+SubClassReference TGParser::
+ParseSubClassReference(Record *CurRec, bool isDefm) {
+  SubClassReference Result;
+  Result.RefLoc = Lex.getLoc();
+
+  if (isDefm)
+    Result.Rec = ParseDefmID();
+  else
+    Result.Rec = ParseClassID();
+  if (Result.Rec == 0) return Result;
+
+  // If there is no template arg list, we're done.
+  if (Lex.getCode() != tgtok::less)
+    return Result;
+  Lex.Lex();  // Eat the '<'
+
+  if (Lex.getCode() == tgtok::greater) {
+    TokError("subclass reference requires a non-empty list of template values");
+    Result.Rec = 0;
+    return Result;
+  }
+
+  Result.TemplateArgs = ParseValueList(CurRec, Result.Rec);
+  if (Result.TemplateArgs.empty()) {
+    Result.Rec = 0;   // Error parsing value list.
+    return Result;
+  }
+
+  if (Lex.getCode() != tgtok::greater) {
+    TokError("expected '>' in template value list");
+    Result.Rec = 0;
+    return Result;
+  }
+  Lex.Lex();
+
+  return Result;
+}
+
+/// ParseSubMultiClassReference - Parse a reference to a subclass or to a
+/// templated submulticlass.  This returns a SubMultiClassRefTy with a null
+/// Record* on error.
+///
+///  SubMultiClassRef ::= MultiClassID
+///  SubMultiClassRef ::= MultiClassID '<' ValueList '>'
+///
+SubMultiClassReference TGParser::
+ParseSubMultiClassReference(MultiClass *CurMC) {
+  SubMultiClassReference Result;
+  Result.RefLoc = Lex.getLoc();
+
+  Result.MC = ParseMultiClassID();
+  if (Result.MC == 0) return Result;
+
+  // If there is no template arg list, we're done.
+  if (Lex.getCode() != tgtok::less)
+    return Result;
+  Lex.Lex();  // Eat the '<'
+
+  if (Lex.getCode() == tgtok::greater) {
+    TokError("subclass reference requires a non-empty list of template values");
+    Result.MC = 0;
+    return Result;
+  }
+
+  Result.TemplateArgs = ParseValueList(&CurMC->Rec, &Result.MC->Rec);
+  if (Result.TemplateArgs.empty()) {
+    Result.MC = 0;   // Error parsing value list.
+    return Result;
+  }
+
+  if (Lex.getCode() != tgtok::greater) {
+    TokError("expected '>' in template value list");
+    Result.MC = 0;
+    return Result;
+  }
+  Lex.Lex();
+
+  return Result;
+}
+
+/// ParseRangePiece - Parse a bit/value range.
+///   RangePiece ::= INTVAL
+///   RangePiece ::= INTVAL '-' INTVAL
+///   RangePiece ::= INTVAL INTVAL
+bool TGParser::ParseRangePiece(std::vector<unsigned> &Ranges) {
+  if (Lex.getCode() != tgtok::IntVal) {
+    TokError("expected integer or bitrange");
+    return true;
+  }
+  int64_t Start = Lex.getCurIntVal();
+  int64_t End;
+
+  if (Start < 0)
+    return TokError("invalid range, cannot be negative");
+
+  switch (Lex.Lex()) {  // eat first character.
+  default:
+    Ranges.push_back(Start);
+    return false;
+  case tgtok::minus:
+    if (Lex.Lex() != tgtok::IntVal) {
+      TokError("expected integer value as end of range");
+      return true;
+    }
+    End = Lex.getCurIntVal();
+    break;
+  case tgtok::IntVal:
+    End = -Lex.getCurIntVal();
+    break;
+  }
+  if (End < 0)
+    return TokError("invalid range, cannot be negative");
+  Lex.Lex();
+
+  // Add to the range.
+  if (Start < End) {
+    for (; Start <= End; ++Start)
+      Ranges.push_back(Start);
+  } else {
+    for (; Start >= End; --Start)
+      Ranges.push_back(Start);
+  }
+  return false;
+}
+
+/// ParseRangeList - Parse a list of scalars and ranges into scalar values.
+///
+///   RangeList ::= RangePiece (',' RangePiece)*
+///
+std::vector<unsigned> TGParser::ParseRangeList() {
+  std::vector<unsigned> Result;
+
+  // Parse the first piece.
+  if (ParseRangePiece(Result))
+    return std::vector<unsigned>();
+  while (Lex.getCode() == tgtok::comma) {
+    Lex.Lex();  // Eat the comma.
+
+    // Parse the next range piece.
+    if (ParseRangePiece(Result))
+      return std::vector<unsigned>();
+  }
+  return Result;
+}
+
+/// ParseOptionalRangeList - Parse either a range list in <>'s or nothing.
+///   OptionalRangeList ::= '<' RangeList '>'
+///   OptionalRangeList ::= /*empty*/
+bool TGParser::ParseOptionalRangeList(std::vector<unsigned> &Ranges) {
+  if (Lex.getCode() != tgtok::less)
+    return false;
+
+  SMLoc StartLoc = Lex.getLoc();
+  Lex.Lex(); // eat the '<'
+
+  // Parse the range list.
+  Ranges = ParseRangeList();
+  if (Ranges.empty()) return true;
+
+  if (Lex.getCode() != tgtok::greater) {
+    TokError("expected '>' at end of range list");
+    return Error(StartLoc, "to match this '<'");
+  }
+  Lex.Lex();   // eat the '>'.
+  return false;
+}
+
+/// ParseOptionalBitList - Parse either a bit list in {}'s or nothing.
+///   OptionalBitList ::= '{' RangeList '}'
+///   OptionalBitList ::= /*empty*/
+bool TGParser::ParseOptionalBitList(std::vector<unsigned> &Ranges) {
+  if (Lex.getCode() != tgtok::l_brace)
+    return false;
+
+  SMLoc StartLoc = Lex.getLoc();
+  Lex.Lex(); // eat the '{'
+
+  // Parse the range list.
+  Ranges = ParseRangeList();
+  if (Ranges.empty()) return true;
+
+  if (Lex.getCode() != tgtok::r_brace) {
+    TokError("expected '}' at end of bit list");
+    return Error(StartLoc, "to match this '{'");
+  }
+  Lex.Lex();   // eat the '}'.
+  return false;
+}
+
+
+/// ParseType - Parse and return a tblgen type.  This returns null on error.
+///
+///   Type ::= STRING                       // string type
+///   Type ::= BIT                          // bit type
+///   Type ::= BITS '<' INTVAL '>'          // bits<x> type
+///   Type ::= INT                          // int type
+///   Type ::= LIST '<' Type '>'            // list<x> type
+///   Type ::= CODE                         // code type
+///   Type ::= DAG                          // dag type
+///   Type ::= ClassID                      // Record Type
+///
+RecTy *TGParser::ParseType() {
+  switch (Lex.getCode()) {
+  default: TokError("Unknown token when expecting a type"); return 0;
+  case tgtok::String: Lex.Lex(); return new StringRecTy();
+  case tgtok::Bit:    Lex.Lex(); return new BitRecTy();
+  case tgtok::Int:    Lex.Lex(); return new IntRecTy();
+  case tgtok::Code:   Lex.Lex(); return new CodeRecTy();
+  case tgtok::Dag:    Lex.Lex(); return new DagRecTy();
+  case tgtok::Id:
+    if (Record *R = ParseClassID()) return new RecordRecTy(R);
+    return 0;
+  case tgtok::Bits: {
+    if (Lex.Lex() != tgtok::less) { // Eat 'bits'
+      TokError("expected '<' after bits type");
+      return 0;
+    }
+    if (Lex.Lex() != tgtok::IntVal) {  // Eat '<'
+      TokError("expected integer in bits<n> type");
+      return 0;
+    }
+    uint64_t Val = Lex.getCurIntVal();
+    if (Lex.Lex() != tgtok::greater) {  // Eat count.
+      TokError("expected '>' at end of bits<n> type");
+      return 0;
+    }
+    Lex.Lex();  // Eat '>'
+    return new BitsRecTy(Val);
+  }
+  case tgtok::List: {
+    if (Lex.Lex() != tgtok::less) { // Eat 'bits'
+      TokError("expected '<' after list type");
+      return 0;
+    }
+    Lex.Lex();  // Eat '<'
+    RecTy *SubType = ParseType();
+    if (SubType == 0) return 0;
+
+    if (Lex.getCode() != tgtok::greater) {
+      TokError("expected '>' at end of list<ty> type");
+      return 0;
+    }
+    Lex.Lex();  // Eat '>'
+    return new ListRecTy(SubType);
+  }
+  }
+}
+
+/// ParseIDValue - Parse an ID as a value and decode what it means.
+///
+///  IDValue ::= ID [def local value]
+///  IDValue ::= ID [def template arg]
+///  IDValue ::= ID [multiclass local value]
+///  IDValue ::= ID [multiclass template argument]
+///  IDValue ::= ID [def name]
+///
+Init *TGParser::ParseIDValue(Record *CurRec) {
+  assert(Lex.getCode() == tgtok::Id && "Expected ID in ParseIDValue");
+  std::string Name = Lex.getCurStrVal();
+  SMLoc Loc = Lex.getLoc();
+  Lex.Lex();
+  return ParseIDValue(CurRec, Name, Loc);
+}
+
+/// ParseIDValue - This is just like ParseIDValue above, but it assumes the ID
+/// has already been read.
+Init *TGParser::ParseIDValue(Record *CurRec,
+                             const std::string &Name, SMLoc NameLoc) {
+  if (CurRec) {
+    if (const RecordVal *RV = CurRec->getValue(Name))
+      return new VarInit(Name, RV->getType());
+
+    std::string TemplateArgName = CurRec->getName()+":"+Name;
+    if (CurRec->isTemplateArg(TemplateArgName)) {
+      const RecordVal *RV = CurRec->getValue(TemplateArgName);
+      assert(RV && "Template arg doesn't exist??");
+      return new VarInit(TemplateArgName, RV->getType());
+    }
+  }
+
+  if (CurMultiClass) {
+    std::string MCName = CurMultiClass->Rec.getName()+"::"+Name;
+    if (CurMultiClass->Rec.isTemplateArg(MCName)) {
+      const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
+      assert(RV && "Template arg doesn't exist??");
+      return new VarInit(MCName, RV->getType());
+    }
+  }
+
+  if (Record *D = Records.getDef(Name))
+    return new DefInit(D);
+
+  Error(NameLoc, "Variable not defined: '" + Name + "'");
+  return 0;
+}
+
+/// ParseOperation - Parse an operator.  This returns null on error.
+///
+/// Operation ::= XOperator ['<' Type '>'] '(' Args ')'
+///
+Init *TGParser::ParseOperation(Record *CurRec) {
+  switch (Lex.getCode()) {
+  default:
+    TokError("unknown operation");
+    return 0;
+    break;
+  case tgtok::XCar:
+  case tgtok::XCdr:
+  case tgtok::XNull:
+  case tgtok::XCast: {  // Value ::= !unop '(' Value ')'
+    UnOpInit::UnaryOp Code;
+    RecTy *Type = 0;
+
+    switch (Lex.getCode()) {
+    default: assert(0 && "Unhandled code!");
+    case tgtok::XCast:
+      Lex.Lex();  // eat the operation
+      Code = UnOpInit::CAST;
+
+      Type = ParseOperatorType();
+
+      if (Type == 0) {
+        TokError("did not get type for unary operator");
+        return 0;
+      }
+
+      break;
+    case tgtok::XCar:
+      Lex.Lex();  // eat the operation
+      Code = UnOpInit::CAR;
+      break;
+    case tgtok::XCdr:
+      Lex.Lex();  // eat the operation
+      Code = UnOpInit::CDR;
+      break;
+    case tgtok::XNull:
+      Lex.Lex();  // eat the operation
+      Code = UnOpInit::LNULL;
+      Type = new IntRecTy;
+      break;
+    }
+    if (Lex.getCode() != tgtok::l_paren) {
+      TokError("expected '(' after unary operator");
+      return 0;
+    }
+    Lex.Lex();  // eat the '('
+
+    Init *LHS = ParseValue(CurRec);
+    if (LHS == 0) return 0;
+
+    if (Code == UnOpInit::CAR
+        || Code == UnOpInit::CDR
+        || Code == UnOpInit::LNULL) {
+      ListInit *LHSl = dynamic_cast<ListInit*>(LHS);
+      StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
+      TypedInit *LHSt = dynamic_cast<TypedInit*>(LHS);
+      if (LHSl == 0 && LHSs == 0 && LHSt == 0) {
+        TokError("expected list or string type argument in unary operator");
+        return 0;
+      }
+      if (LHSt) {
+        ListRecTy *LType = dynamic_cast<ListRecTy*>(LHSt->getType());
+        StringRecTy *SType = dynamic_cast<StringRecTy*>(LHSt->getType());
+        if (LType == 0 && SType == 0) {
+          TokError("expected list or string type argumnet in unary operator");
+          return 0;
+        }
+      }
+
+      if (Code == UnOpInit::CAR
+          || Code == UnOpInit::CDR) {
+        if (LHSl == 0 && LHSt == 0) {
+          TokError("expected list type argumnet in unary operator");
+          return 0;
+        }
+
+        if (LHSl && LHSl->getSize() == 0) {
+          TokError("empty list argument in unary operator");
+          return 0;
+        }
+        if (LHSl) {
+          Init *Item = LHSl->getElement(0);
+          TypedInit *Itemt = dynamic_cast<TypedInit*>(Item);
+          if (Itemt == 0) {
+            TokError("untyped list element in unary operator");
+            return 0;
+          }
+          if (Code == UnOpInit::CAR) {
+            Type = Itemt->getType();
+          } else {
+            Type = new ListRecTy(Itemt->getType());
+          }
+        } else {
+          assert(LHSt && "expected list type argument in unary operator");
+          ListRecTy *LType = dynamic_cast<ListRecTy*>(LHSt->getType());
+          if (LType == 0) {
+            TokError("expected list type argumnet in unary operator");
+            return 0;
+          }
+          if (Code == UnOpInit::CAR) {
+            Type = LType->getElementType();
+          } else {
+            Type = LType;
+          }
+        }
+      }
+    }
+
+    if (Lex.getCode() != tgtok::r_paren) {
+      TokError("expected ')' in unary operator");
+      return 0;
+    }
+    Lex.Lex();  // eat the ')'
+    return (new UnOpInit(Code, LHS, Type))->Fold(CurRec, CurMultiClass);
+  }
+
+  case tgtok::XConcat:
+  case tgtok::XSRA:
+  case tgtok::XSRL:
+  case tgtok::XSHL:
+  case tgtok::XEq:
+  case tgtok::XStrConcat:
+  case tgtok::XNameConcat: {  // Value ::= !binop '(' Value ',' Value ')'
+    BinOpInit::BinaryOp Code;
+    RecTy *Type = 0;
+
+
+    switch (Lex.getCode()) {
+    default: assert(0 && "Unhandled code!");
+    case tgtok::XConcat:
+      Lex.Lex();  // eat the operation
+      Code = BinOpInit::CONCAT;
+      Type = new DagRecTy();
+      break;
+    case tgtok::XSRA:
+      Lex.Lex();  // eat the operation
+      Code = BinOpInit::SRA;
+      Type = new IntRecTy();
+      break;
+    case tgtok::XSRL:
+      Lex.Lex();  // eat the operation
+      Code = BinOpInit::SRL;
+      Type = new IntRecTy();
+      break;
+    case tgtok::XSHL:
+      Lex.Lex();  // eat the operation
+      Code = BinOpInit::SHL;
+      Type = new IntRecTy();
+      break;
+    case tgtok::XEq:  
+      Lex.Lex();  // eat the operation
+      Code = BinOpInit::EQ;
+      Type = new IntRecTy();
+      break;
+    case tgtok::XStrConcat:
+      Lex.Lex();  // eat the operation
+      Code = BinOpInit::STRCONCAT;
+      Type = new StringRecTy();
+      break;
+    case tgtok::XNameConcat:
+      Lex.Lex();  // eat the operation
+      Code = BinOpInit::NAMECONCAT;
+
+      Type = ParseOperatorType();
+
+      if (Type == 0) {
+        TokError("did not get type for binary operator");
+        return 0;
+      }
+
+      break;
+    }
+    if (Lex.getCode() != tgtok::l_paren) {
+      TokError("expected '(' after binary operator");
+      return 0;
+    }
+    Lex.Lex();  // eat the '('
+
+    Init *LHS = ParseValue(CurRec);
+    if (LHS == 0) return 0;
+
+    if (Lex.getCode() != tgtok::comma) {
+      TokError("expected ',' in binary operator");
+      return 0;
+    }
+    Lex.Lex();  // eat the ','
+
+    Init *RHS = ParseValue(CurRec);
+    if (RHS == 0) return 0;
+
+    if (Lex.getCode() != tgtok::r_paren) {
+      TokError("expected ')' in binary operator");
+      return 0;
+    }
+    Lex.Lex();  // eat the ')'
+    return (new BinOpInit(Code, LHS, RHS, Type))->Fold(CurRec, CurMultiClass);
+  }
+
+  case tgtok::XIf:
+  case tgtok::XForEach:
+  case tgtok::XSubst: {  // Value ::= !ternop '(' Value ',' Value ',' Value ')'
+    TernOpInit::TernaryOp Code;
+    RecTy *Type = 0;
+
+
+    tgtok::TokKind LexCode = Lex.getCode();
+    Lex.Lex();  // eat the operation
+    switch (LexCode) {
+    default: assert(0 && "Unhandled code!");
+    case tgtok::XIf:
+      Code = TernOpInit::IF;
+      break;
+    case tgtok::XForEach:
+      Code = TernOpInit::FOREACH;
+      break;
+    case tgtok::XSubst:
+      Code = TernOpInit::SUBST;
+      break;
+    }
+    if (Lex.getCode() != tgtok::l_paren) {
+      TokError("expected '(' after ternary operator");
+      return 0;
+    }
+    Lex.Lex();  // eat the '('
+
+    Init *LHS = ParseValue(CurRec);
+    if (LHS == 0) return 0;
+
+    if (Lex.getCode() != tgtok::comma) {
+      TokError("expected ',' in ternary operator");
+      return 0;
+    }
+    Lex.Lex();  // eat the ','
+
+    Init *MHS = ParseValue(CurRec);
+    if (MHS == 0) return 0;
+
+    if (Lex.getCode() != tgtok::comma) {
+      TokError("expected ',' in ternary operator");
+      return 0;
+    }
+    Lex.Lex();  // eat the ','
+
+    Init *RHS = ParseValue(CurRec);
+    if (RHS == 0) return 0;
+
+    if (Lex.getCode() != tgtok::r_paren) {
+      TokError("expected ')' in binary operator");
+      return 0;
+    }
+    Lex.Lex();  // eat the ')'
+
+    switch (LexCode) {
+    default: assert(0 && "Unhandled code!");
+    case tgtok::XIf: {
+      TypedInit *MHSt = dynamic_cast<TypedInit *>(MHS);
+      TypedInit *RHSt = dynamic_cast<TypedInit *>(RHS);
+      if (MHSt == 0 || RHSt == 0) {
+        TokError("could not get type for !if");
+        return 0;
+      }
+      if (MHSt->getType()->typeIsConvertibleTo(RHSt->getType())) {
+        Type = RHSt->getType();
+      } else if (RHSt->getType()->typeIsConvertibleTo(MHSt->getType())) {
+        Type = MHSt->getType();
+      } else {
+        TokError("inconsistent types for !if");
+        return 0;
+      }
+      break;
+    }
+    case tgtok::XForEach: {
+      TypedInit *MHSt = dynamic_cast<TypedInit *>(MHS);
+      if (MHSt == 0) {
+        TokError("could not get type for !foreach");
+        return 0;
+      }
+      Type = MHSt->getType();
+      break;
+    }
+    case tgtok::XSubst: {
+      TypedInit *RHSt = dynamic_cast<TypedInit *>(RHS);
+      if (RHSt == 0) {
+        TokError("could not get type for !subst");
+        return 0;
+      }
+      Type = RHSt->getType();
+      break;
+    }
+    }
+    return (new TernOpInit(Code, LHS, MHS, RHS, Type))->Fold(CurRec,
+                                                             CurMultiClass);
+  }
+  }
+  TokError("could not parse operation");
+  return 0;
+}
+
+/// ParseOperatorType - Parse a type for an operator.  This returns
+/// null on error.
+///
+/// OperatorType ::= '<' Type '>'
+///
+RecTy *TGParser::ParseOperatorType() {
+  RecTy *Type = 0;
+
+  if (Lex.getCode() != tgtok::less) {
+    TokError("expected type name for operator");
+    return 0;
+  }
+  Lex.Lex();  // eat the <
+
+  Type = ParseType();
+
+  if (Type == 0) {
+    TokError("expected type name for operator");
+    return 0;
+  }
+
+  if (Lex.getCode() != tgtok::greater) {
+    TokError("expected type name for operator");
+    return 0;
+  }
+  Lex.Lex();  // eat the >
+
+  return Type;
+}
+
+
+/// ParseSimpleValue - Parse a tblgen value.  This returns null on error.
+///
+///   SimpleValue ::= IDValue
+///   SimpleValue ::= INTVAL
+///   SimpleValue ::= STRVAL+
+///   SimpleValue ::= CODEFRAGMENT
+///   SimpleValue ::= '?'
+///   SimpleValue ::= '{' ValueList '}'
+///   SimpleValue ::= ID '<' ValueListNE '>'
+///   SimpleValue ::= '[' ValueList ']'
+///   SimpleValue ::= '(' IDValue DagArgList ')'
+///   SimpleValue ::= CONCATTOK '(' Value ',' Value ')'
+///   SimpleValue ::= SHLTOK '(' Value ',' Value ')'
+///   SimpleValue ::= SRATOK '(' Value ',' Value ')'
+///   SimpleValue ::= SRLTOK '(' Value ',' Value ')'
+///   SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')'
+///
+Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) {
+  Init *R = 0;
+  switch (Lex.getCode()) {
+  default: TokError("Unknown token when parsing a value"); break;
+  case tgtok::IntVal: R = new IntInit(Lex.getCurIntVal()); Lex.Lex(); break;
+  case tgtok::StrVal: {
+    std::string Val = Lex.getCurStrVal();
+    Lex.Lex();
+
+    // Handle multiple consecutive concatenated strings.
+    while (Lex.getCode() == tgtok::StrVal) {
+      Val += Lex.getCurStrVal();
+      Lex.Lex();
+    }
+
+    R = new StringInit(Val);
+    break;
+  }
+  case tgtok::CodeFragment:
+    R = new CodeInit(Lex.getCurStrVal()); Lex.Lex(); break;
+  case tgtok::question: R = new UnsetInit(); Lex.Lex(); break;
+  case tgtok::Id: {
+    SMLoc NameLoc = Lex.getLoc();
+    std::string Name = Lex.getCurStrVal();
+    if (Lex.Lex() != tgtok::less)  // consume the Id.
+      return ParseIDValue(CurRec, Name, NameLoc);    // Value ::= IDValue
+
+    // Value ::= ID '<' ValueListNE '>'
+    if (Lex.Lex() == tgtok::greater) {
+      TokError("expected non-empty value list");
+      return 0;
+    }
+
+    // This is a CLASS<initvalslist> expression.  This is supposed to synthesize
+    // a new anonymous definition, deriving from CLASS<initvalslist> with no
+    // body.
+    Record *Class = Records.getClass(Name);
+    if (!Class) {
+      Error(NameLoc, "Expected a class name, got '" + Name + "'");
+      return 0;
+    }
+
+    std::vector<Init*> ValueList = ParseValueList(CurRec, Class);
+    if (ValueList.empty()) return 0;
+
+    if (Lex.getCode() != tgtok::greater) {
+      TokError("expected '>' at end of value list");
+      return 0;
+    }
+    Lex.Lex();  // eat the '>'
+
+    // Create the new record, set it as CurRec temporarily.
+    static unsigned AnonCounter = 0;
+    Record *NewRec = new Record("anonymous.val."+utostr(AnonCounter++),NameLoc);
+    SubClassReference SCRef;
+    SCRef.RefLoc = NameLoc;
+    SCRef.Rec = Class;
+    SCRef.TemplateArgs = ValueList;
+    // Add info about the subclass to NewRec.
+    if (AddSubClass(NewRec, SCRef))
+      return 0;
+    NewRec->resolveReferences();
+    Records.addDef(NewRec);
+
+    // The result of the expression is a reference to the new record.
+    return new DefInit(NewRec);
+  }
+  case tgtok::l_brace: {           // Value ::= '{' ValueList '}'
+    SMLoc BraceLoc = Lex.getLoc();
+    Lex.Lex(); // eat the '{'
+    std::vector<Init*> Vals;
+
+    if (Lex.getCode() != tgtok::r_brace) {
+      Vals = ParseValueList(CurRec);
+      if (Vals.empty()) return 0;
+    }
+    if (Lex.getCode() != tgtok::r_brace) {
+      TokError("expected '}' at end of bit list value");
+      return 0;
+    }
+    Lex.Lex();  // eat the '}'
+
+    BitsInit *Result = new BitsInit(Vals.size());
+    for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
+      Init *Bit = Vals[i]->convertInitializerTo(new BitRecTy());
+      if (Bit == 0) {
+        Error(BraceLoc, "Element #" + utostr(i) + " (" + Vals[i]->getAsString()+
+              ") is not convertable to a bit");
+        return 0;
+      }
+      Result->setBit(Vals.size()-i-1, Bit);
+    }
+    return Result;
+  }
+  case tgtok::l_square: {          // Value ::= '[' ValueList ']'
+    Lex.Lex(); // eat the '['
+    std::vector<Init*> Vals;
+
+    RecTy *DeducedEltTy = 0;
+    ListRecTy *GivenListTy = 0;
+
+    if (ItemType != 0) {
+      ListRecTy *ListType = dynamic_cast<ListRecTy*>(ItemType);
+      if (ListType == 0) {
+        std::stringstream s;
+        s << "Type mismatch for list, expected list type, got "
+          << ItemType->getAsString();
+        TokError(s.str());
+      }
+      GivenListTy = ListType;
+    }
+
+    if (Lex.getCode() != tgtok::r_square) {
+      Vals = ParseValueList(CurRec, 0,
+                            GivenListTy ? GivenListTy->getElementType() : 0);
+      if (Vals.empty()) return 0;
+    }
+    if (Lex.getCode() != tgtok::r_square) {
+      TokError("expected ']' at end of list value");
+      return 0;
+    }
+    Lex.Lex();  // eat the ']'
+
+    RecTy *GivenEltTy = 0;
+    if (Lex.getCode() == tgtok::less) {
+      // Optional list element type
+      Lex.Lex();  // eat the '<'
+
+      GivenEltTy = ParseType();
+      if (GivenEltTy == 0) {
+        // Couldn't parse element type
+        return 0;
+      }
+
+      if (Lex.getCode() != tgtok::greater) {
+        TokError("expected '>' at end of list element type");
+        return 0;
+      }
+      Lex.Lex();  // eat the '>'
+    }
+
+    // Check elements
+    RecTy *EltTy = 0;
+    for (std::vector<Init *>::iterator i = Vals.begin(), ie = Vals.end();
+         i != ie;
+         ++i) {
+      TypedInit *TArg = dynamic_cast<TypedInit*>(*i);
+      if (TArg == 0) {
+        TokError("Untyped list element");
+        return 0;
+      }
+      if (EltTy != 0) {
+        EltTy = resolveTypes(EltTy, TArg->getType());
+        if (EltTy == 0) {
+          TokError("Incompatible types in list elements");
+          return 0;
+        }
+      } else {
+        EltTy = TArg->getType();
+      }
+    }
+
+    if (GivenEltTy != 0) {
+      if (EltTy != 0) {
+        // Verify consistency
+        if (!EltTy->typeIsConvertibleTo(GivenEltTy)) {
+          TokError("Incompatible types in list elements");
+          return 0;
+        }
+      }
+      EltTy = GivenEltTy;
+    }
+
+    if (EltTy == 0) {
+      if (ItemType == 0) {
+        TokError("No type for list");
+        return 0;
+      }
+      DeducedEltTy = GivenListTy->getElementType();
+    } else {
+      // Make sure the deduced type is compatible with the given type
+      if (GivenListTy) {
+        if (!EltTy->typeIsConvertibleTo(GivenListTy->getElementType())) {
+          TokError("Element type mismatch for list");
+          return 0;
+        }
+      }
+      DeducedEltTy = EltTy;
+    }
+
+    return new ListInit(Vals, DeducedEltTy);
+  }
+  case tgtok::l_paren: {         // Value ::= '(' IDValue DagArgList ')'
+    Lex.Lex();   // eat the '('
+    if (Lex.getCode() != tgtok::Id
+        && Lex.getCode() != tgtok::XCast
+        && Lex.getCode() != tgtok::XNameConcat) {
+      TokError("expected identifier in dag init");
+      return 0;
+    }
+
+    Init *Operator = 0;
+    if (Lex.getCode() == tgtok::Id) {
+      Operator = ParseIDValue(CurRec);
+      if (Operator == 0) return 0;
+    } else {
+      Operator = ParseOperation(CurRec);
+      if (Operator == 0) return 0;
+    }
+
+    // If the operator name is present, parse it.
+    std::string OperatorName;
+    if (Lex.getCode() == tgtok::colon) {
+      if (Lex.Lex() != tgtok::VarName) { // eat the ':'
+        TokError("expected variable name in dag operator");
+        return 0;
+      }
+      OperatorName = Lex.getCurStrVal();
+      Lex.Lex();  // eat the VarName.
+    }
+
+    std::vector<std::pair<llvm::Init*, std::string> > DagArgs;
+    if (Lex.getCode() != tgtok::r_paren) {
+      DagArgs = ParseDagArgList(CurRec);
+      if (DagArgs.empty()) return 0;
+    }
+
+    if (Lex.getCode() != tgtok::r_paren) {
+      TokError("expected ')' in dag init");
+      return 0;
+    }
+    Lex.Lex();  // eat the ')'
+
+    return new DagInit(Operator, OperatorName, DagArgs);
+    break;
+  }
+
+  case tgtok::XCar:
+  case tgtok::XCdr:
+  case tgtok::XNull:
+  case tgtok::XCast:  // Value ::= !unop '(' Value ')'
+  case tgtok::XConcat:
+  case tgtok::XSRA:
+  case tgtok::XSRL:
+  case tgtok::XSHL:
+  case tgtok::XEq:
+  case tgtok::XStrConcat:
+  case tgtok::XNameConcat:  // Value ::= !binop '(' Value ',' Value ')'
+  case tgtok::XIf:
+  case tgtok::XForEach:
+  case tgtok::XSubst: {  // Value ::= !ternop '(' Value ',' Value ',' Value ')'
+    return ParseOperation(CurRec);
+    break;
+  }
+  }
+
+  return R;
+}
+
+/// ParseValue - Parse a tblgen value.  This returns null on error.
+///
+///   Value       ::= SimpleValue ValueSuffix*
+///   ValueSuffix ::= '{' BitList '}'
+///   ValueSuffix ::= '[' BitList ']'
+///   ValueSuffix ::= '.' ID
+///
+Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType) {
+  Init *Result = ParseSimpleValue(CurRec, ItemType);
+  if (Result == 0) return 0;
+
+  // Parse the suffixes now if present.
+  while (1) {
+    switch (Lex.getCode()) {
+    default: return Result;
+    case tgtok::l_brace: {
+      SMLoc CurlyLoc = Lex.getLoc();
+      Lex.Lex(); // eat the '{'
+      std::vector<unsigned> Ranges = ParseRangeList();
+      if (Ranges.empty()) return 0;
+
+      // Reverse the bitlist.
+      std::reverse(Ranges.begin(), Ranges.end());
+      Result = Result->convertInitializerBitRange(Ranges);
+      if (Result == 0) {
+        Error(CurlyLoc, "Invalid bit range for value");
+        return 0;
+      }
+
+      // Eat the '}'.
+      if (Lex.getCode() != tgtok::r_brace) {
+        TokError("expected '}' at end of bit range list");
+        return 0;
+      }
+      Lex.Lex();
+      break;
+    }
+    case tgtok::l_square: {
+      SMLoc SquareLoc = Lex.getLoc();
+      Lex.Lex(); // eat the '['
+      std::vector<unsigned> Ranges = ParseRangeList();
+      if (Ranges.empty()) return 0;
+
+      Result = Result->convertInitListSlice(Ranges);
+      if (Result == 0) {
+        Error(SquareLoc, "Invalid range for list slice");
+        return 0;
+      }
+
+      // Eat the ']'.
+      if (Lex.getCode() != tgtok::r_square) {
+        TokError("expected ']' at end of list slice");
+        return 0;
+      }
+      Lex.Lex();
+      break;
+    }
+    case tgtok::period:
+      if (Lex.Lex() != tgtok::Id) {  // eat the .
+        TokError("expected field identifier after '.'");
+        return 0;
+      }
+      if (!Result->getFieldType(Lex.getCurStrVal())) {
+        TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" +
+                 Result->getAsString() + "'");
+        return 0;
+      }
+      Result = new FieldInit(Result, Lex.getCurStrVal());
+      Lex.Lex();  // eat field name
+      break;
+    }
+  }
+}
+
+/// ParseDagArgList - Parse the argument list for a dag literal expression.
+///
+///    ParseDagArgList ::= Value (':' VARNAME)?
+///    ParseDagArgList ::= ParseDagArgList ',' Value (':' VARNAME)?
+std::vector<std::pair<llvm::Init*, std::string> >
+TGParser::ParseDagArgList(Record *CurRec) {
+  std::vector<std::pair<llvm::Init*, std::string> > Result;
+
+  while (1) {
+    Init *Val = ParseValue(CurRec);
+    if (Val == 0) return std::vector<std::pair<llvm::Init*, std::string> >();
+
+    // If the variable name is present, add it.
+    std::string VarName;
+    if (Lex.getCode() == tgtok::colon) {
+      if (Lex.Lex() != tgtok::VarName) { // eat the ':'
+        TokError("expected variable name in dag literal");
+        return std::vector<std::pair<llvm::Init*, std::string> >();
+      }
+      VarName = Lex.getCurStrVal();
+      Lex.Lex();  // eat the VarName.
+    }
+
+    Result.push_back(std::make_pair(Val, VarName));
+
+    if (Lex.getCode() != tgtok::comma) break;
+    Lex.Lex(); // eat the ','
+  }
+
+  return Result;
+}
+
+
+/// ParseValueList - Parse a comma separated list of values, returning them as a
+/// vector.  Note that this always expects to be able to parse at least one
+/// value.  It returns an empty list if this is not possible.
+///
+///   ValueList ::= Value (',' Value)
+///
+std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec,
+                                            RecTy *EltTy) {
+  std::vector<Init*> Result;
+  RecTy *ItemType = EltTy;
+  unsigned int ArgN = 0;
+  if (ArgsRec != 0 && EltTy == 0) {
+    const std::vector<std::string> &TArgs = ArgsRec->getTemplateArgs();
+    const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]);
+    assert(RV && "Template argument record not found??");
+    ItemType = RV->getType();
+    ++ArgN;
+  }
+  Result.push_back(ParseValue(CurRec, ItemType));
+  if (Result.back() == 0) return std::vector<Init*>();
+
+  while (Lex.getCode() == tgtok::comma) {
+    Lex.Lex();  // Eat the comma
+
+    if (ArgsRec != 0 && EltTy == 0) {
+      const std::vector<std::string> &TArgs = ArgsRec->getTemplateArgs();
+      if (ArgN >= TArgs.size()) {
+        TokError("too many template arguments");
+        return std::vector<Init*>();
+      }
+      const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]);
+      assert(RV && "Template argument record not found??");
+      ItemType = RV->getType();
+      ++ArgN;
+    }
+    Result.push_back(ParseValue(CurRec, ItemType));
+    if (Result.back() == 0) return std::vector<Init*>();
+  }
+
+  return Result;
+}
+
+
+/// ParseDeclaration - Read a declaration, returning the name of field ID, or an
+/// empty string on error.  This can happen in a number of different context's,
+/// including within a def or in the template args for a def (which which case
+/// CurRec will be non-null) and within the template args for a multiclass (in
+/// which case CurRec will be null, but CurMultiClass will be set).  This can
+/// also happen within a def that is within a multiclass, which will set both
+/// CurRec and CurMultiClass.
+///
+///  Declaration ::= FIELD? Type ID ('=' Value)?
+///
+std::string TGParser::ParseDeclaration(Record *CurRec,
+                                       bool ParsingTemplateArgs) {
+  // Read the field prefix if present.
+  bool HasField = Lex.getCode() == tgtok::Field;
+  if (HasField) Lex.Lex();
+
+  RecTy *Type = ParseType();
+  if (Type == 0) return "";
+
+  if (Lex.getCode() != tgtok::Id) {
+    TokError("Expected identifier in declaration");
+    return "";
+  }
+
+  SMLoc IdLoc = Lex.getLoc();
+  std::string DeclName = Lex.getCurStrVal();
+  Lex.Lex();
+
+  if (ParsingTemplateArgs) {
+    if (CurRec) {
+      DeclName = CurRec->getName() + ":" + DeclName;
+    } else {
+      assert(CurMultiClass);
+    }
+    if (CurMultiClass)
+      DeclName = CurMultiClass->Rec.getName() + "::" + DeclName;
+  }
+
+  // Add the value.
+  if (AddValue(CurRec, IdLoc, RecordVal(DeclName, Type, HasField)))
+    return "";
+
+  // If a value is present, parse it.
+  if (Lex.getCode() == tgtok::equal) {
+    Lex.Lex();
+    SMLoc ValLoc = Lex.getLoc();
+    Init *Val = ParseValue(CurRec, Type);
+    if (Val == 0 ||
+        SetValue(CurRec, ValLoc, DeclName, std::vector<unsigned>(), Val))
+      return "";
+  }
+
+  return DeclName;
+}
+
+/// ParseTemplateArgList - Read a template argument list, which is a non-empty
+/// sequence of template-declarations in <>'s.  If CurRec is non-null, these are
+/// template args for a def, which may or may not be in a multiclass.  If null,
+/// these are the template args for a multiclass.
+///
+///    TemplateArgList ::= '<' Declaration (',' Declaration)* '>'
+///
+bool TGParser::ParseTemplateArgList(Record *CurRec) {
+  assert(Lex.getCode() == tgtok::less && "Not a template arg list!");
+  Lex.Lex(); // eat the '<'
+
+  Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec;
+
+  // Read the first declaration.
+  std::string TemplArg = ParseDeclaration(CurRec, true/*templateargs*/);
+  if (TemplArg.empty())
+    return true;
+
+  TheRecToAddTo->addTemplateArg(TemplArg);
+
+  while (Lex.getCode() == tgtok::comma) {
+    Lex.Lex(); // eat the ','
+
+    // Read the following declarations.
+    TemplArg = ParseDeclaration(CurRec, true/*templateargs*/);
+    if (TemplArg.empty())
+      return true;
+    TheRecToAddTo->addTemplateArg(TemplArg);
+  }
+
+  if (Lex.getCode() != tgtok::greater)
+    return TokError("expected '>' at end of template argument list");
+  Lex.Lex(); // eat the '>'.
+  return false;
+}
+
+
+/// ParseBodyItem - Parse a single item at within the body of a def or class.
+///
+///   BodyItem ::= Declaration ';'
+///   BodyItem ::= LET ID OptionalBitList '=' Value ';'
+bool TGParser::ParseBodyItem(Record *CurRec) {
+  if (Lex.getCode() != tgtok::Let) {
+    if (ParseDeclaration(CurRec, false).empty())
+      return true;
+
+    if (Lex.getCode() != tgtok::semi)
+      return TokError("expected ';' after declaration");
+    Lex.Lex();
+    return false;
+  }
+
+  // LET ID OptionalRangeList '=' Value ';'
+  if (Lex.Lex() != tgtok::Id)
+    return TokError("expected field identifier after let");
+
+  SMLoc IdLoc = Lex.getLoc();
+  std::string FieldName = Lex.getCurStrVal();
+  Lex.Lex();  // eat the field name.
+
+  std::vector<unsigned> BitList;
+  if (ParseOptionalBitList(BitList))
+    return true;
+  std::reverse(BitList.begin(), BitList.end());
+
+  if (Lex.getCode() != tgtok::equal)
+    return TokError("expected '=' in let expression");
+  Lex.Lex();  // eat the '='.
+
+  RecordVal *Field = CurRec->getValue(FieldName);
+  if (Field == 0)
+    return TokError("Value '" + FieldName + "' unknown!");
+
+  RecTy *Type = Field->getType();
+
+  Init *Val = ParseValue(CurRec, Type);
+  if (Val == 0) return true;
+
+  if (Lex.getCode() != tgtok::semi)
+    return TokError("expected ';' after let expression");
+  Lex.Lex();
+
+  return SetValue(CurRec, IdLoc, FieldName, BitList, Val);
+}
+
+/// ParseBody - Read the body of a class or def.  Return true on error, false on
+/// success.
+///
+///   Body     ::= ';'
+///   Body     ::= '{' BodyList '}'
+///   BodyList BodyItem*
+///
+bool TGParser::ParseBody(Record *CurRec) {
+  // If this is a null definition, just eat the semi and return.
+  if (Lex.getCode() == tgtok::semi) {
+    Lex.Lex();
+    return false;
+  }
+
+  if (Lex.getCode() != tgtok::l_brace)
+    return TokError("Expected ';' or '{' to start body");
+  // Eat the '{'.
+  Lex.Lex();
+
+  while (Lex.getCode() != tgtok::r_brace)
+    if (ParseBodyItem(CurRec))
+      return true;
+
+  // Eat the '}'.
+  Lex.Lex();
+  return false;
+}
+
+/// ParseObjectBody - Parse the body of a def or class.  This consists of an
+/// optional ClassList followed by a Body.  CurRec is the current def or class
+/// that is being parsed.
+///
+///   ObjectBody      ::= BaseClassList Body
+///   BaseClassList   ::= /*empty*/
+///   BaseClassList   ::= ':' BaseClassListNE
+///   BaseClassListNE ::= SubClassRef (',' SubClassRef)*
+///
+bool TGParser::ParseObjectBody(Record *CurRec) {
+  // If there is a baseclass list, read it.
+  if (Lex.getCode() == tgtok::colon) {
+    Lex.Lex();
+
+    // Read all of the subclasses.
+    SubClassReference SubClass = ParseSubClassReference(CurRec, false);
+    while (1) {
+      // Check for error.
+      if (SubClass.Rec == 0) return true;
+
+      // Add it.
+      if (AddSubClass(CurRec, SubClass))
+        return true;
+
+      if (Lex.getCode() != tgtok::comma) break;
+      Lex.Lex(); // eat ','.
+      SubClass = ParseSubClassReference(CurRec, false);
+    }
+  }
+
+  // Process any variables on the let stack.
+  for (unsigned i = 0, e = LetStack.size(); i != e; ++i)
+    for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j)
+      if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name,
+                   LetStack[i][j].Bits, LetStack[i][j].Value))
+        return true;
+
+  return ParseBody(CurRec);
+}
+
+/// ParseDef - Parse and return a top level or multiclass def, return the record
+/// corresponding to it.  This returns null on error.
+///
+///   DefInst ::= DEF ObjectName ObjectBody
+///
+bool TGParser::ParseDef(MultiClass *CurMultiClass) {
+  SMLoc DefLoc = Lex.getLoc();
+  assert(Lex.getCode() == tgtok::Def && "Unknown tok");
+  Lex.Lex();  // Eat the 'def' token.
+
+  // Parse ObjectName and make a record for it.
+  Record *CurRec = new Record(ParseObjectName(), DefLoc);
+
+  if (!CurMultiClass) {
+    // Top-level def definition.
+
+    // Ensure redefinition doesn't happen.
+    if (Records.getDef(CurRec->getName())) {
+      Error(DefLoc, "def '" + CurRec->getName() + "' already defined");
+      return true;
+    }
+    Records.addDef(CurRec);
+  } else {
+    // Otherwise, a def inside a multiclass, add it to the multiclass.
+    for (unsigned i = 0, e = CurMultiClass->DefPrototypes.size(); i != e; ++i)
+      if (CurMultiClass->DefPrototypes[i]->getName() == CurRec->getName()) {
+        Error(DefLoc, "def '" + CurRec->getName() +
+              "' already defined in this multiclass!");
+        return true;
+      }
+    CurMultiClass->DefPrototypes.push_back(CurRec);
+  }
+
+  if (ParseObjectBody(CurRec))
+    return true;
+
+  if (CurMultiClass == 0)  // Def's in multiclasses aren't really defs.
+    CurRec->resolveReferences();
+
+  // If ObjectBody has template arguments, it's an error.
+  assert(CurRec->getTemplateArgs().empty() && "How'd this get template args?");
+
+  if (CurMultiClass) {
+    // Copy the template arguments for the multiclass into the def.
+    const std::vector<std::string> &TArgs =
+                                CurMultiClass->Rec.getTemplateArgs();
+
+    for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
+      const RecordVal *RV = CurMultiClass->Rec.getValue(TArgs[i]);
+      assert(RV && "Template arg doesn't exist?");
+      CurRec->addValue(*RV);
+    }
+  }
+
+  return false;
+}
+
+
+/// ParseClass - Parse a tblgen class definition.
+///
+///   ClassInst ::= CLASS ID TemplateArgList? ObjectBody
+///
+bool TGParser::ParseClass() {
+  assert(Lex.getCode() == tgtok::Class && "Unexpected token!");
+  Lex.Lex();
+
+  if (Lex.getCode() != tgtok::Id)
+    return TokError("expected class name after 'class' keyword");
+
+  Record *CurRec = Records.getClass(Lex.getCurStrVal());
+  if (CurRec) {
+    // If the body was previously defined, this is an error.
+    if (!CurRec->getValues().empty() ||
+        !CurRec->getSuperClasses().empty() ||
+        !CurRec->getTemplateArgs().empty())
+      return TokError("Class '" + CurRec->getName() + "' already defined");
+  } else {
+    // If this is the first reference to this class, create and add it.
+    CurRec = new Record(Lex.getCurStrVal(), Lex.getLoc());
+    Records.addClass(CurRec);
+  }
+  Lex.Lex(); // eat the name.
+
+  // If there are template args, parse them.
+  if (Lex.getCode() == tgtok::less)
+    if (ParseTemplateArgList(CurRec))
+      return true;
+
+  // Finally, parse the object body.
+  return ParseObjectBody(CurRec);
+}
+
+/// ParseLetList - Parse a non-empty list of assignment expressions into a list
+/// of LetRecords.
+///
+///   LetList ::= LetItem (',' LetItem)*
+///   LetItem ::= ID OptionalRangeList '=' Value
+///
+std::vector<LetRecord> TGParser::ParseLetList() {
+  std::vector<LetRecord> Result;
+
+  while (1) {
+    if (Lex.getCode() != tgtok::Id) {
+      TokError("expected identifier in let definition");
+      return std::vector<LetRecord>();
+    }
+    std::string Name = Lex.getCurStrVal();
+    SMLoc NameLoc = Lex.getLoc();
+    Lex.Lex();  // Eat the identifier.
+
+    // Check for an optional RangeList.
+    std::vector<unsigned> Bits;
+    if (ParseOptionalRangeList(Bits))
+      return std::vector<LetRecord>();
+    std::reverse(Bits.begin(), Bits.end());
+
+    if (Lex.getCode() != tgtok::equal) {
+      TokError("expected '=' in let expression");
+      return std::vector<LetRecord>();
+    }
+    Lex.Lex();  // eat the '='.
+
+    Init *Val = ParseValue(0);
+    if (Val == 0) return std::vector<LetRecord>();
+
+    // Now that we have everything, add the record.
+    Result.push_back(LetRecord(Name, Bits, Val, NameLoc));
+
+    if (Lex.getCode() != tgtok::comma)
+      return Result;
+    Lex.Lex();  // eat the comma.
+  }
+}
+
+/// ParseTopLevelLet - Parse a 'let' at top level.  This can be a couple of
+/// different related productions. This works inside multiclasses too.
+///
+///   Object ::= LET LetList IN '{' ObjectList '}'
+///   Object ::= LET LetList IN Object
+///
+bool TGParser::ParseTopLevelLet(MultiClass *CurMultiClass) {
+  assert(Lex.getCode() == tgtok::Let && "Unexpected token");
+  Lex.Lex();
+
+  // Add this entry to the let stack.
+  std::vector<LetRecord> LetInfo = ParseLetList();
+  if (LetInfo.empty()) return true;
+  LetStack.push_back(LetInfo);
+
+  if (Lex.getCode() != tgtok::In)
+    return TokError("expected 'in' at end of top-level 'let'");
+  Lex.Lex();
+
+  // If this is a scalar let, just handle it now
+  if (Lex.getCode() != tgtok::l_brace) {
+    // LET LetList IN Object
+    if (ParseObject(CurMultiClass))
+      return true;
+  } else {   // Object ::= LETCommand '{' ObjectList '}'
+    SMLoc BraceLoc = Lex.getLoc();
+    // Otherwise, this is a group let.
+    Lex.Lex();  // eat the '{'.
+
+    // Parse the object list.
+    if (ParseObjectList(CurMultiClass))
+      return true;
+
+    if (Lex.getCode() != tgtok::r_brace) {
+      TokError("expected '}' at end of top level let command");
+      return Error(BraceLoc, "to match this '{'");
+    }
+    Lex.Lex();
+  }
+
+  // Outside this let scope, this let block is not active.
+  LetStack.pop_back();
+  return false;
+}
+
+/// ParseMultiClass - Parse a multiclass definition.
+///
+///  MultiClassInst ::= MULTICLASS ID TemplateArgList?
+///                     ':' BaseMultiClassList '{' MultiClassDef+ '}'
+///
+bool TGParser::ParseMultiClass() {
+  assert(Lex.getCode() == tgtok::MultiClass && "Unexpected token");
+  Lex.Lex();  // Eat the multiclass token.
+
+  if (Lex.getCode() != tgtok::Id)
+    return TokError("expected identifier after multiclass for name");
+  std::string Name = Lex.getCurStrVal();
+
+  if (MultiClasses.count(Name))
+    return TokError("multiclass '" + Name + "' already defined");
+
+  CurMultiClass = MultiClasses[Name] = new MultiClass(Name, Lex.getLoc());
+  Lex.Lex();  // Eat the identifier.
+
+  // If there are template args, parse them.
+  if (Lex.getCode() == tgtok::less)
+    if (ParseTemplateArgList(0))
+      return true;
+
+  bool inherits = false;
+
+  // If there are submulticlasses, parse them.
+  if (Lex.getCode() == tgtok::colon) {
+    inherits = true;
+
+    Lex.Lex();
+
+    // Read all of the submulticlasses.
+    SubMultiClassReference SubMultiClass =
+      ParseSubMultiClassReference(CurMultiClass);
+    while (1) {
+      // Check for error.
+      if (SubMultiClass.MC == 0) return true;
+
+      // Add it.
+      if (AddSubMultiClass(CurMultiClass, SubMultiClass))
+        return true;
+
+      if (Lex.getCode() != tgtok::comma) break;
+      Lex.Lex(); // eat ','.
+      SubMultiClass = ParseSubMultiClassReference(CurMultiClass);
+    }
+  }
+
+  if (Lex.getCode() != tgtok::l_brace) {
+    if (!inherits)
+      return TokError("expected '{' in multiclass definition");
+    else if (Lex.getCode() != tgtok::semi)
+      return TokError("expected ';' in multiclass definition");
+    else
+      Lex.Lex();  // eat the ';'.
+  } else {
+    if (Lex.Lex() == tgtok::r_brace)  // eat the '{'.
+      return TokError("multiclass must contain at least one def");
+
+    while (Lex.getCode() != tgtok::r_brace) {
+      switch (Lex.getCode()) {
+        default:
+          return TokError("expected 'let', 'def' or 'defm' in multiclass body");
+        case tgtok::Let:
+        case tgtok::Def:
+        case tgtok::Defm:
+          if (ParseObject(CurMultiClass))
+            return true;
+         break;
+      }
+    }
+    Lex.Lex();  // eat the '}'.
+  }
+
+  CurMultiClass = 0;
+  return false;
+}
+
+/// ParseDefm - Parse the instantiation of a multiclass.
+///
+///   DefMInst ::= DEFM ID ':' DefmSubClassRef ';'
+///
+bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
+  assert(Lex.getCode() == tgtok::Defm && "Unexpected token!");
+  if (Lex.Lex() != tgtok::Id)  // eat the defm.
+    return TokError("expected identifier after defm");
+
+  SMLoc DefmPrefixLoc = Lex.getLoc();
+  std::string DefmPrefix = Lex.getCurStrVal();
+  if (Lex.Lex() != tgtok::colon)
+    return TokError("expected ':' after defm identifier");
+
+  // Keep track of the new generated record definitions.
+  std::vector<Record*> NewRecDefs;
+
+  // This record also inherits from a regular class (non-multiclass)?
+  bool InheritFromClass = false;
+
+  // eat the colon.
+  Lex.Lex();
+
+  SMLoc SubClassLoc = Lex.getLoc();
+  SubClassReference Ref = ParseSubClassReference(0, true);
+
+  while (1) {
+    if (Ref.Rec == 0) return true;
+
+    // To instantiate a multiclass, we need to first get the multiclass, then
+    // instantiate each def contained in the multiclass with the SubClassRef
+    // template parameters.
+    MultiClass *MC = MultiClasses[Ref.Rec->getName()];
+    assert(MC && "Didn't lookup multiclass correctly?");
+    std::vector<Init*> &TemplateVals = Ref.TemplateArgs;
+
+    // Verify that the correct number of template arguments were specified.
+    const std::vector<std::string> &TArgs = MC->Rec.getTemplateArgs();
+    if (TArgs.size() < TemplateVals.size())
+      return Error(SubClassLoc,
+                   "more template args specified than multiclass expects");
+
+    // Loop over all the def's in the multiclass, instantiating each one.
+    for (unsigned i = 0, e = MC->DefPrototypes.size(); i != e; ++i) {
+      Record *DefProto = MC->DefPrototypes[i];
+
+      // Add in the defm name
+      std::string DefName = DefProto->getName();
+      std::string::size_type idx = DefName.find("#NAME#");
+      if (idx != std::string::npos) {
+        DefName.replace(idx, 6, DefmPrefix);
+      } else {
+        // Add the suffix to the defm name to get the new name.
+        DefName = DefmPrefix + DefName;
+      }
+
+      Record *CurRec = new Record(DefName, DefmPrefixLoc);
+
+      SubClassReference Ref;
+      Ref.RefLoc = DefmPrefixLoc;
+      Ref.Rec = DefProto;
+      AddSubClass(CurRec, Ref);
+
+      // Loop over all of the template arguments, setting them to the specified
+      // value or leaving them as the default if necessary.
+      for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
+        // Check if a value is specified for this temp-arg.
+        if (i < TemplateVals.size()) {
+          // Set it now.
+          if (SetValue(CurRec, DefmPrefixLoc, TArgs[i], std::vector<unsigned>(),
+                       TemplateVals[i]))
+            return true;
+
+          // Resolve it next.
+          CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i]));
+
+          // Now remove it.
+          CurRec->removeValue(TArgs[i]);
+
+        } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
+          return Error(SubClassLoc,
+                       "value not specified for template argument #"+
+                       utostr(i) + " (" + TArgs[i] + ") of multiclassclass '" +
+                       MC->Rec.getName() + "'");
+        }
+      }
+
+      // If the mdef is inside a 'let' expression, add to each def.
+      for (unsigned i = 0, e = LetStack.size(); i != e; ++i)
+        for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j)
+          if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name,
+                       LetStack[i][j].Bits, LetStack[i][j].Value)) {
+            Error(DefmPrefixLoc, "when instantiating this defm");
+            return true;
+          }
+
+      // Ensure redefinition doesn't happen.
+      if (Records.getDef(CurRec->getName()))
+        return Error(DefmPrefixLoc, "def '" + CurRec->getName() +
+                     "' already defined, instantiating defm with subdef '" +
+                     DefProto->getName() + "'");
+
+      // Don't create a top level definition for defm inside multiclasses,
+      // instead, only update the prototypes and bind the template args
+      // with the new created definition.
+      if (CurMultiClass) {
+        for (unsigned i = 0, e = CurMultiClass->DefPrototypes.size();
+             i != e; ++i) {
+          if (CurMultiClass->DefPrototypes[i]->getName() == CurRec->getName()) {
+            Error(DefmPrefixLoc, "defm '" + CurRec->getName() +
+                  "' already defined in this multiclass!");
+            return 0;
+          }
+        }
+        CurMultiClass->DefPrototypes.push_back(CurRec);
+
+        // Copy the template arguments for the multiclass into the new def.
+        const std::vector<std::string> &TA =
+          CurMultiClass->Rec.getTemplateArgs();
+
+        for (unsigned i = 0, e = TA.size(); i != e; ++i) {
+          const RecordVal *RV = CurMultiClass->Rec.getValue(TA[i]);
+          assert(RV && "Template arg doesn't exist?");
+          CurRec->addValue(*RV);
+        }
+      } else {
+        Records.addDef(CurRec);
+      }
+
+      NewRecDefs.push_back(CurRec);
+    }
+
+    if (Lex.getCode() != tgtok::comma) break;
+    Lex.Lex(); // eat ','.
+
+    SubClassLoc = Lex.getLoc();
+
+    // A defm can inherit from regular classes (non-multiclass) as
+    // long as they come in the end of the inheritance list.
+    InheritFromClass = (Records.getClass(Lex.getCurStrVal()) != 0);
+
+    if (InheritFromClass)
+      break;
+
+    Ref = ParseSubClassReference(0, true);
+  }
+
+  if (InheritFromClass) {
+    // Process all the classes to inherit as if they were part of a
+    // regular 'def' and inherit all record values.
+    SubClassReference SubClass = ParseSubClassReference(0, false);
+    while (1) {
+      // Check for error.
+      if (SubClass.Rec == 0) return true;
+
+      // Get the expanded definition prototypes and teach them about
+      // the record values the current class to inherit has
+      for (unsigned i = 0, e = NewRecDefs.size(); i != e; ++i) {
+        Record *CurRec = NewRecDefs[i];
+
+        // Add it.
+        if (AddSubClass(CurRec, SubClass))
+          return true;
+
+        // Process any variables on the let stack.
+        for (unsigned i = 0, e = LetStack.size(); i != e; ++i)
+          for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j)
+            if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name,
+                         LetStack[i][j].Bits, LetStack[i][j].Value))
+              return true;
+      }
+
+      if (Lex.getCode() != tgtok::comma) break;
+      Lex.Lex(); // eat ','.
+      SubClass = ParseSubClassReference(0, false);
+    }
+  }
+
+  if (!CurMultiClass)
+    for (unsigned i = 0, e = NewRecDefs.size(); i != e; ++i)
+      NewRecDefs[i]->resolveReferences();
+
+  if (Lex.getCode() != tgtok::semi)
+    return TokError("expected ';' at end of defm");
+  Lex.Lex();
+
+  return false;
+}
+
+/// ParseObject
+///   Object ::= ClassInst
+///   Object ::= DefInst
+///   Object ::= MultiClassInst
+///   Object ::= DefMInst
+///   Object ::= LETCommand '{' ObjectList '}'
+///   Object ::= LETCommand Object
+bool TGParser::ParseObject(MultiClass *MC) {
+  switch (Lex.getCode()) {
+  default: assert(0 && "This is not an object");
+  case tgtok::Let:   return ParseTopLevelLet(MC);
+  case tgtok::Def:   return ParseDef(MC);
+  case tgtok::Defm:  return ParseDefm(MC);
+  case tgtok::Class: return ParseClass();
+  case tgtok::MultiClass: return ParseMultiClass();
+  }
+}
+
+/// ParseObjectList
+///   ObjectList :== Object*
+bool TGParser::ParseObjectList(MultiClass *MC) {
+  while (isObjectStart(Lex.getCode())) {
+    if (ParseObject(MC))
+      return true;
+  }
+  return false;
+}
+
+bool TGParser::ParseFile() {
+  Lex.Lex(); // Prime the lexer.
+  if (ParseObjectList()) return true;
+
+  // If we have unread input at the end of the file, report it.
+  if (Lex.getCode() == tgtok::Eof)
+    return false;
+
+  return TokError("Unexpected input at top level");
+}
+
diff --git a/src/LLVM/utils/TableGen/TGParser.h b/src/LLVM/utils/TableGen/TGParser.h
new file mode 100644
index 0000000..0aee931
--- /dev/null
+++ b/src/LLVM/utils/TableGen/TGParser.h
@@ -0,0 +1,112 @@
+//===- TGParser.h - Parser for TableGen Files -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class represents the Parser for tablegen files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TGPARSER_H
+#define TGPARSER_H
+
+#include "TGLexer.h"
+#include "llvm/Support/SourceMgr.h"
+#include <map>
+
+namespace llvm {
+  class Record;
+  class RecordVal;
+  struct RecTy;
+  struct Init;
+  struct MultiClass;
+  struct SubClassReference;
+  struct SubMultiClassReference;
+  
+  struct LetRecord {
+    std::string Name;
+    std::vector<unsigned> Bits;
+    Init *Value;
+    SMLoc Loc;
+    LetRecord(const std::string &N, const std::vector<unsigned> &B, Init *V,
+              SMLoc L)
+      : Name(N), Bits(B), Value(V), Loc(L) {
+    }
+  };
+  
+class TGParser {
+  TGLexer Lex;
+  std::vector<std::vector<LetRecord> > LetStack;
+  std::map<std::string, MultiClass*> MultiClasses;
+  
+  /// CurMultiClass - If we are parsing a 'multiclass' definition, this is the 
+  /// current value.
+  MultiClass *CurMultiClass;
+public:
+  TGParser(SourceMgr &SrcMgr) : Lex(SrcMgr), CurMultiClass(0) {}
+  
+  /// ParseFile - Main entrypoint for parsing a tblgen file.  These parser
+  /// routines return true on error, or false on success.
+  bool ParseFile();
+  
+  bool Error(SMLoc L, const std::string &Msg) const {
+    Lex.PrintError(L, Msg);
+    return true;
+  }
+  bool TokError(const std::string &Msg) const {
+    return Error(Lex.getLoc(), Msg);
+  }
+private:  // Semantic analysis methods.
+  bool AddValue(Record *TheRec, SMLoc Loc, const RecordVal &RV);
+  bool SetValue(Record *TheRec, SMLoc Loc, const std::string &ValName, 
+                const std::vector<unsigned> &BitList, Init *V);
+  bool AddSubClass(Record *Rec, SubClassReference &SubClass);
+  bool AddSubMultiClass(MultiClass *CurMC,
+                        SubMultiClassReference &SubMultiClass);
+
+private:  // Parser methods.
+  bool ParseObjectList(MultiClass *MC = 0);
+  bool ParseObject(MultiClass *MC);
+  bool ParseClass();
+  bool ParseMultiClass();
+  bool ParseDefm(MultiClass *CurMultiClass);
+  bool ParseDef(MultiClass *CurMultiClass);
+  bool ParseTopLevelLet(MultiClass *CurMultiClass);
+  std::vector<LetRecord> ParseLetList();
+
+  bool ParseObjectBody(Record *CurRec);
+  bool ParseBody(Record *CurRec);
+  bool ParseBodyItem(Record *CurRec);
+
+  bool ParseTemplateArgList(Record *CurRec);
+  std::string ParseDeclaration(Record *CurRec, bool ParsingTemplateArgs);
+
+  SubClassReference ParseSubClassReference(Record *CurRec, bool isDefm);
+  SubMultiClassReference ParseSubMultiClassReference(MultiClass *CurMC);
+
+  Init *ParseIDValue(Record *CurRec);
+  Init *ParseIDValue(Record *CurRec, const std::string &Name, SMLoc NameLoc);
+  Init *ParseSimpleValue(Record *CurRec, RecTy *ItemType = 0);
+  Init *ParseValue(Record *CurRec, RecTy *ItemType = 0);
+  std::vector<Init*> ParseValueList(Record *CurRec, Record *ArgsRec = 0, RecTy *EltTy = 0);
+  std::vector<std::pair<llvm::Init*, std::string> > ParseDagArgList(Record *);
+  bool ParseOptionalRangeList(std::vector<unsigned> &Ranges);
+  bool ParseOptionalBitList(std::vector<unsigned> &Ranges);
+  std::vector<unsigned> ParseRangeList();
+  bool ParseRangePiece(std::vector<unsigned> &Ranges);
+  RecTy *ParseType();
+  Init *ParseOperation(Record *CurRec);
+  RecTy *ParseOperatorType();
+  std::string ParseObjectName();
+  Record *ParseClassID();
+  MultiClass *ParseMultiClassID();
+  Record *ParseDefmID();
+};
+  
+} // end namespace llvm
+
+#endif
diff --git a/src/LLVM/utils/TableGen/TGValueTypes.cpp b/src/LLVM/utils/TableGen/TGValueTypes.cpp
new file mode 100644
index 0000000..122d085
--- /dev/null
+++ b/src/LLVM/utils/TableGen/TGValueTypes.cpp
@@ -0,0 +1,106 @@
+//===- ValueTypes.cpp - Tablegen extended ValueType implementation --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The EVT type is used by tablegen as well as in LLVM. In order to handle
+// extended types, the EVT type uses support functions that call into
+// LLVM's type system code. These aren't accessible in tablegen, so this
+// file provides simple replacements.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/ValueTypes.h"
+#include <map>
+#include <vector>
+using namespace llvm;
+
+namespace llvm {
+
+class Type {
+public:
+  virtual unsigned getSizeInBits() const = 0;
+  virtual ~Type() {}
+};
+
+}
+
+class ExtendedIntegerType : public Type {
+  unsigned BitWidth;
+public:
+  explicit ExtendedIntegerType(unsigned bits)
+    : BitWidth(bits) {}
+  unsigned getSizeInBits() const {
+    return getBitWidth();
+  }
+  unsigned getBitWidth() const {
+    return BitWidth;
+  }
+};
+
+class ExtendedVectorType : public Type {
+  EVT ElementType;
+  unsigned NumElements;
+public:
+  ExtendedVectorType(EVT elty, unsigned num)
+    : ElementType(elty), NumElements(num) {}
+  unsigned getSizeInBits() const {
+    return getNumElements() * getElementType().getSizeInBits();
+  }
+  EVT getElementType() const {
+    return ElementType;
+  }
+  unsigned getNumElements() const {
+    return NumElements;
+  }
+};
+
+static std::map<unsigned, const Type *>
+  ExtendedIntegerTypeMap;
+static std::map<std::pair<uintptr_t, uintptr_t>, const Type *>
+  ExtendedVectorTypeMap;
+
+bool EVT::isExtendedFloatingPoint() const {
+  assert(isExtended() && "Type is not extended!");
+  // Extended floating-point types are not supported yet.
+  return false;
+}
+
+bool EVT::isExtendedInteger() const {
+  assert(isExtended() && "Type is not extended!");
+  return dynamic_cast<const ExtendedIntegerType *>(LLVMTy) != 0;
+}
+
+bool EVT::isExtendedVector() const {
+  assert(isExtended() && "Type is not extended!");
+  return dynamic_cast<const ExtendedVectorType *>(LLVMTy) != 0;
+}
+
+bool EVT::isExtended64BitVector() const {
+  assert(isExtended() && "Type is not extended!");
+  return isExtendedVector() && getSizeInBits() == 64;
+}
+
+bool EVT::isExtended128BitVector() const {
+  assert(isExtended() && "Type is not extended!");
+  return isExtendedVector() && getSizeInBits() == 128;
+}
+
+EVT EVT::getExtendedVectorElementType() const {
+  assert(isExtendedVector() && "Type is not an extended vector!");
+  return static_cast<const ExtendedVectorType *>(LLVMTy)->getElementType();
+}
+
+unsigned EVT::getExtendedVectorNumElements() const {
+  assert(isExtendedVector() && "Type is not an extended vector!");
+  return static_cast<const ExtendedVectorType *>(LLVMTy)->getNumElements();
+}
+
+unsigned EVT::getExtendedSizeInBits() const {
+  assert(isExtended() && "Type is not extended!");
+  return LLVMTy->getSizeInBits();
+}
diff --git a/src/LLVM/utils/TableGen/TableGen.cpp b/src/LLVM/utils/TableGen/TableGen.cpp
new file mode 100644
index 0000000..ebd163d
--- /dev/null
+++ b/src/LLVM/utils/TableGen/TableGen.cpp
@@ -0,0 +1,341 @@
+//===- TableGen.cpp - Top-Level TableGen implementation -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// TableGen is a tool which can be used to build up a description of something,
+// then invoke one or more "tablegen backends" to emit information about the
+// description in some predefined format.  In practice, this is used by the LLVM
+// code generators to automate generation of a code generator through a
+// high-level description of the target.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AsmMatcherEmitter.h"
+#include "AsmWriterEmitter.h"
+#include "CallingConvEmitter.h"
+#include "ClangASTNodesEmitter.h"
+#include "ClangAttrEmitter.h"
+#include "ClangDiagnosticsEmitter.h"
+#include "CodeEmitterGen.h"
+#include "DAGISelEmitter.h"
+#include "DisassemblerEmitter.h"
+#include "EDEmitter.h"
+#include "FastISelEmitter.h"
+#include "InstrEnumEmitter.h"
+#include "InstrInfoEmitter.h"
+#include "IntrinsicEmitter.h"
+#include "LLVMCConfigurationEmitter.h"
+#include "NeonEmitter.h"
+#include "OptParserEmitter.h"
+#include "Record.h"
+#include "RegisterInfoEmitter.h"
+#include "ARMDecoderEmitter.h"
+#include "SubtargetEmitter.h"
+#include "TGParser.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Signals.h"
+#include <algorithm>
+#include <cstdio>
+using namespace llvm;
+
+enum ActionType {
+  PrintRecords,
+  GenEmitter,
+  GenRegisterEnums, GenRegister, GenRegisterHeader,
+  GenInstrEnums, GenInstrs, GenAsmWriter, GenAsmMatcher,
+  GenARMDecoder,
+  GenDisassembler,
+  GenCallingConv,
+  GenClangAttrClasses,
+  GenClangAttrList,
+  GenClangDiagsDefs,
+  GenClangDiagGroups,
+  GenClangDeclNodes,
+  GenClangStmtNodes,
+  GenDAGISel,
+  GenFastISel,
+  GenOptParserDefs, GenOptParserImpl,
+  GenSubtarget,
+  GenIntrinsic,
+  GenTgtIntrinsic,
+  GenLLVMCConf,
+  GenEDInfo,
+  GenArmNeon,
+  GenArmNeonSema,
+  PrintEnums
+};
+
+namespace {
+  cl::opt<ActionType>
+  Action(cl::desc("Action to perform:"),
+         cl::values(clEnumValN(PrintRecords, "print-records",
+                               "Print all records to stdout (default)"),
+                    clEnumValN(GenEmitter, "gen-emitter",
+                               "Generate machine code emitter"),
+                    clEnumValN(GenRegisterEnums, "gen-register-enums",
+                               "Generate enum values for registers"),
+                    clEnumValN(GenRegister, "gen-register-desc",
+                               "Generate a register info description"),
+                    clEnumValN(GenRegisterHeader, "gen-register-desc-header",
+                               "Generate a register info description header"),
+                    clEnumValN(GenInstrEnums, "gen-instr-enums",
+                               "Generate enum values for instructions"),
+                    clEnumValN(GenInstrs, "gen-instr-desc",
+                               "Generate instruction descriptions"),
+                    clEnumValN(GenCallingConv, "gen-callingconv",
+                               "Generate calling convention descriptions"),
+                    clEnumValN(GenAsmWriter, "gen-asm-writer",
+                               "Generate assembly writer"),
+                    clEnumValN(GenARMDecoder, "gen-arm-decoder",
+                               "Generate decoders for ARM/Thumb"),
+                    clEnumValN(GenDisassembler, "gen-disassembler",
+                               "Generate disassembler"),
+                    clEnumValN(GenAsmMatcher, "gen-asm-matcher",
+                               "Generate assembly instruction matcher"),
+                    clEnumValN(GenDAGISel, "gen-dag-isel",
+                               "Generate a DAG instruction selector"),
+                    clEnumValN(GenFastISel, "gen-fast-isel",
+                               "Generate a \"fast\" instruction selector"),
+                    clEnumValN(GenOptParserDefs, "gen-opt-parser-defs",
+                               "Generate option definitions"),
+                    clEnumValN(GenOptParserImpl, "gen-opt-parser-impl",
+                               "Generate option parser implementation"),
+                    clEnumValN(GenSubtarget, "gen-subtarget",
+                               "Generate subtarget enumerations"),
+                    clEnumValN(GenIntrinsic, "gen-intrinsic",
+                               "Generate intrinsic information"),
+                    clEnumValN(GenTgtIntrinsic, "gen-tgt-intrinsic",
+                               "Generate target intrinsic information"),
+                    clEnumValN(GenClangAttrClasses, "gen-clang-attr-classes",
+                               "Generate clang attribute clases"),
+                    clEnumValN(GenClangAttrList, "gen-clang-attr-list",
+                               "Generate a clang attribute list"),
+                    clEnumValN(GenClangDiagsDefs, "gen-clang-diags-defs",
+                               "Generate Clang diagnostics definitions"),
+                    clEnumValN(GenClangDiagGroups, "gen-clang-diag-groups",
+                               "Generate Clang diagnostic groups"),
+                    clEnumValN(GenClangDeclNodes, "gen-clang-decl-nodes",
+                               "Generate Clang AST statement nodes"),
+                    clEnumValN(GenClangStmtNodes, "gen-clang-stmt-nodes",
+                               "Generate Clang AST statement nodes"),
+                    clEnumValN(GenLLVMCConf, "gen-llvmc",
+                               "Generate LLVMC configuration library"),
+                    clEnumValN(GenEDInfo, "gen-enhanced-disassembly-info",
+                               "Generate enhanced disassembly info"),
+                    clEnumValN(GenArmNeon, "gen-arm-neon",
+                               "Generate arm_neon.h for clang"),
+                    clEnumValN(GenArmNeonSema, "gen-arm-neon-sema",
+                               "Generate ARM NEON sema support for clang"),
+                    clEnumValN(PrintEnums, "print-enums",
+                               "Print enum values for a class"),
+                    clEnumValEnd));
+
+  cl::opt<std::string>
+  Class("class", cl::desc("Print Enum list for this class"),
+        cl::value_desc("class name"));
+
+  cl::opt<std::string>
+  OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"),
+                 cl::init("-"));
+
+  cl::opt<std::string>
+  InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
+
+  cl::list<std::string>
+  IncludeDirs("I", cl::desc("Directory of include files"),
+              cl::value_desc("directory"), cl::Prefix);
+
+  cl::opt<std::string>
+  ClangComponent("clang-component",
+                 cl::desc("Only use warnings from specified component"),
+                 cl::value_desc("component"), cl::Hidden);
+}
+
+
+// FIXME: Eliminate globals from tblgen.
+RecordKeeper llvm::Records;
+
+static SourceMgr SrcMgr;
+
+void llvm::PrintError(SMLoc ErrorLoc, const std::string &Msg) {
+  SrcMgr.PrintMessage(ErrorLoc, Msg, "error");
+}
+
+
+
+/// ParseFile - this function begins the parsing of the specified tablegen
+/// file.
+static bool ParseFile(const std::string &Filename,
+                      const std::vector<std::string> &IncludeDirs,
+                      SourceMgr &SrcMgr) {
+  std::string ErrorStr;
+  MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrorStr);
+  if (F == 0) {
+    errs() << "Could not open input file '" << Filename << "': "
+           << ErrorStr <<"\n";
+    return true;
+  }
+
+  // Tell SrcMgr about this buffer, which is what TGParser will pick up.
+  SrcMgr.AddNewSourceBuffer(F, SMLoc());
+
+  // Record the location of the include directory so that the lexer can find
+  // it later.
+  SrcMgr.setIncludeDirs(IncludeDirs);
+
+  TGParser Parser(SrcMgr);
+
+  return Parser.ParseFile();
+}
+
+int main(int argc, char **argv) {
+  sys::PrintStackTraceOnErrorSignal();
+  PrettyStackTraceProgram X(argc, argv);
+  cl::ParseCommandLineOptions(argc, argv);
+
+
+  // Parse the input file.
+  if (ParseFile(InputFilename, IncludeDirs, SrcMgr))
+    return 1;
+
+  std::string Error;
+  raw_fd_ostream Out(OutputFilename.c_str(), Error);
+  if (!Error.empty()) {
+    errs() << argv[0] << ": error opening " << OutputFilename
+           << ":" << Error << "\n";
+    return 1;
+  }
+
+  // Make sure the file gets removed if *gasp* tablegen crashes...
+  sys::RemoveFileOnSignal(sys::Path(OutputFilename));
+
+  try {
+    switch (Action) {
+    case PrintRecords:
+      Out << Records;           // No argument, dump all contents
+      break;
+    case GenEmitter:
+      CodeEmitterGen(Records).run(Out);
+      break;
+
+    case GenRegisterEnums:
+      RegisterInfoEmitter(Records).runEnums(Out);
+      break;
+    case GenRegister:
+      RegisterInfoEmitter(Records).run(Out);
+      break;
+    case GenRegisterHeader:
+      RegisterInfoEmitter(Records).runHeader(Out);
+      break;
+    case GenInstrEnums:
+      InstrEnumEmitter(Records).run(Out);
+      break;
+    case GenInstrs:
+      InstrInfoEmitter(Records).run(Out);
+      break;
+    case GenCallingConv:
+      CallingConvEmitter(Records).run(Out);
+      break;
+    case GenAsmWriter:
+      AsmWriterEmitter(Records).run(Out);
+      break;
+    case GenARMDecoder:
+      ARMDecoderEmitter(Records).run(Out);
+      break;
+    case GenAsmMatcher:
+      AsmMatcherEmitter(Records).run(Out);
+      break;
+    case GenClangAttrClasses:
+      ClangAttrClassEmitter(Records).run(Out);
+      break;
+    case GenClangAttrList:
+      ClangAttrListEmitter(Records).run(Out);
+      break;
+    case GenClangDiagsDefs:
+      ClangDiagsDefsEmitter(Records, ClangComponent).run(Out);
+      break;
+    case GenClangDiagGroups:
+      ClangDiagGroupsEmitter(Records).run(Out);
+      break;
+    case GenClangDeclNodes:
+      ClangASTNodesEmitter(Records, "Decl", "Decl").run(Out);
+      ClangDeclContextEmitter(Records).run(Out);
+      break;
+    case GenClangStmtNodes:
+      ClangASTNodesEmitter(Records, "Stmt", "").run(Out);
+      break;
+    case GenDisassembler:
+      DisassemblerEmitter(Records).run(Out);
+      break;
+    case GenOptParserDefs:
+      OptParserEmitter(Records, true).run(Out);
+      break;
+    case GenOptParserImpl:
+      OptParserEmitter(Records, false).run(Out);
+      break;
+    case GenDAGISel:
+      DAGISelEmitter(Records).run(Out);
+      break;
+    case GenFastISel:
+      FastISelEmitter(Records).run(Out);
+      break;
+    case GenSubtarget:
+      SubtargetEmitter(Records).run(Out);
+      break;
+    case GenIntrinsic:
+      IntrinsicEmitter(Records).run(Out);
+      break;
+    case GenTgtIntrinsic:
+      IntrinsicEmitter(Records, true).run(Out);
+      break;
+    case GenLLVMCConf:
+      LLVMCConfigurationEmitter(Records).run(Out);
+      break;
+    case GenEDInfo:
+      EDEmitter(Records).run(Out);
+      break;
+    case GenArmNeon:
+      NeonEmitter(Records).run(Out);
+      break;
+    case GenArmNeonSema:
+      NeonEmitter(Records).runHeader(Out);
+      break;
+    case PrintEnums:
+    {
+      std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class);
+      for (unsigned i = 0, e = Recs.size(); i != e; ++i)
+        Out << Recs[i]->getName() << ", ";
+      Out << "\n";
+      break;
+    }
+    default:
+      assert(1 && "Invalid Action");
+      return 1;
+    }
+
+    return 0;
+
+  } catch (const TGError &Error) {
+    errs() << argv[0] << ": error:\n";
+    PrintError(Error.getLoc(), Error.getMessage());
+
+  } catch (const std::string &Error) {
+    errs() << argv[0] << ": " << Error << "\n";
+  } catch (const char *Error) {
+    errs() << argv[0] << ": " << Error << "\n";
+  } catch (...) {
+    errs() << argv[0] << ": Unknown unexpected exception occurred.\n";
+  }
+
+  if (OutputFilename != "-")
+    std::remove(OutputFilename.c_str());    // Remove the file, it's broken
+  return 1;
+}
diff --git a/src/LLVM/utils/TableGen/TableGenBackend.cpp b/src/LLVM/utils/TableGen/TableGenBackend.cpp
new file mode 100644
index 0000000..b3e33b5
--- /dev/null
+++ b/src/LLVM/utils/TableGen/TableGenBackend.cpp
@@ -0,0 +1,25 @@
+//===- TableGenBackend.cpp - Base class for TableGen Backends ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides useful services for TableGen backends...
+//
+//===----------------------------------------------------------------------===//
+
+#include "TableGenBackend.h"
+#include "Record.h"
+using namespace llvm;
+
+void TableGenBackend::EmitSourceFileHeader(const std::string &Desc,
+                                           raw_ostream &OS) const {
+  OS << "//===- TableGen'erated file -------------------------------------*-"
+       " C++ -*-===//\n//\n// " << Desc << "\n//\n// Automatically generate"
+       "d file, do not edit!\n//\n//===------------------------------------"
+       "----------------------------------===//\n\n";
+}
+
diff --git a/src/LLVM/utils/TableGen/TableGenBackend.h b/src/LLVM/utils/TableGen/TableGenBackend.h
new file mode 100644
index 0000000..9c2b948
--- /dev/null
+++ b/src/LLVM/utils/TableGen/TableGenBackend.h
@@ -0,0 +1,43 @@
+//===- TableGenBackend.h - Base class for TableGen Backends -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The TableGenBackend class is provided as a common interface for all TableGen
+// backends.  It provides useful services and an standardized interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TABLEGENBACKEND_H
+#define TABLEGENBACKEND_H
+
+#include "llvm/Support/raw_ostream.h"
+#include <string>
+
+namespace llvm {
+
+class Record;
+class RecordKeeper;
+
+struct TableGenBackend {
+  virtual ~TableGenBackend() {}
+
+  // run - All TableGen backends should implement the run method, which should
+  // be the main entry point.
+  virtual void run(raw_ostream &OS) = 0;
+
+
+public:   // Useful helper routines...
+  /// EmitSourceFileHeader - Output a LLVM style file header to the specified
+  /// ostream.
+  void EmitSourceFileHeader(const std::string &Desc, raw_ostream &OS) const;
+
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/utils/TableGen/X86DisassemblerShared.h b/src/LLVM/utils/TableGen/X86DisassemblerShared.h
new file mode 100644
index 0000000..0417e9d
--- /dev/null
+++ b/src/LLVM/utils/TableGen/X86DisassemblerShared.h
@@ -0,0 +1,38 @@
+//===- X86DisassemblerShared.h - Emitter shared header ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef X86DISASSEMBLERSHARED_H
+#define X86DISASSEMBLERSHARED_H
+
+#include <string>
+#include <string.h>
+
+#define INSTRUCTION_SPECIFIER_FIELDS       \
+  bool                    filtered;        \
+  InstructionContext      insnContext;     \
+  std::string             name;            \
+                                           \
+  InstructionSpecifier() {                 \
+    filtered = false;                      \
+    insnContext = IC;                      \
+    name = "";                             \
+    modifierType = MODIFIER_NONE;          \
+    modifierBase = 0;                      \
+    memset(operands, 0, sizeof(operands)); \
+  }
+
+#define INSTRUCTION_IDS           \
+  InstrUID   instructionIDs[256];
+
+#include "../../lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h"
+
+#undef INSTRUCTION_SPECIFIER_FIELDS
+#undef INSTRUCTION_IDS
+
+#endif
diff --git a/src/LLVM/utils/TableGen/X86DisassemblerTables.cpp b/src/LLVM/utils/TableGen/X86DisassemblerTables.cpp
new file mode 100644
index 0000000..2176224
--- /dev/null
+++ b/src/LLVM/utils/TableGen/X86DisassemblerTables.cpp
@@ -0,0 +1,603 @@
+//===- X86DisassemblerTables.cpp - Disassembler tables ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is part of the X86 Disassembler Emitter.
+// It contains the implementation of the disassembler tables.
+// Documentation for the disassembler emitter in general can be found in
+//  X86DisasemblerEmitter.h.
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86DisassemblerShared.h"
+#include "X86DisassemblerTables.h"
+
+#include "TableGenBackend.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Format.h"
+
+using namespace llvm;
+using namespace X86Disassembler;
+  
+/// inheritsFrom - Indicates whether all instructions in one class also belong
+///   to another class.
+///
+/// @param child  - The class that may be the subset
+/// @param parent - The class that may be the superset
+/// @return       - True if child is a subset of parent, false otherwise.
+static inline bool inheritsFrom(InstructionContext child,
+                                InstructionContext parent) {
+  if (child == parent)
+    return true;
+  
+  switch (parent) {
+  case IC:
+    return true;
+  case IC_64BIT:
+    return(inheritsFrom(child, IC_64BIT_REXW)   ||
+           inheritsFrom(child, IC_64BIT_OPSIZE) ||
+           inheritsFrom(child, IC_64BIT_XD)     ||
+           inheritsFrom(child, IC_64BIT_XS));
+  case IC_OPSIZE:
+    return(inheritsFrom(child, IC_64BIT_OPSIZE));
+  case IC_XD:
+    return(inheritsFrom(child, IC_64BIT_XD));
+  case IC_XS:
+    return(inheritsFrom(child, IC_64BIT_XS));
+  case IC_64BIT_REXW:
+    return(inheritsFrom(child, IC_64BIT_REXW_XS) ||
+           inheritsFrom(child, IC_64BIT_REXW_XD) ||
+           inheritsFrom(child, IC_64BIT_REXW_OPSIZE));
+  case IC_64BIT_OPSIZE:
+    return(inheritsFrom(child, IC_64BIT_REXW_OPSIZE));
+  case IC_64BIT_XD:
+    return(inheritsFrom(child, IC_64BIT_REXW_XD));
+  case IC_64BIT_XS:
+    return(inheritsFrom(child, IC_64BIT_REXW_XS));
+  case IC_64BIT_REXW_XD:
+    return false;
+  case IC_64BIT_REXW_XS:
+    return false;
+  case IC_64BIT_REXW_OPSIZE:
+    return false;
+  default:
+    return false;
+  }
+}
+
+/// outranks - Indicates whether, if an instruction has two different applicable
+///   classes, which class should be preferred when performing decode.  This
+///   imposes a total ordering (ties are resolved toward "lower")
+///
+/// @param upper  - The class that may be preferable
+/// @param lower  - The class that may be less preferable
+/// @return       - True if upper is to be preferred, false otherwise.
+static inline bool outranks(InstructionContext upper, 
+                            InstructionContext lower) {
+  assert(upper < IC_max);
+  assert(lower < IC_max);
+  
+#define ENUM_ENTRY(n, r, d) r,
+  static int ranks[IC_max] = {
+    INSTRUCTION_CONTEXTS
+  };
+#undef ENUM_ENTRY
+  
+  return (ranks[upper] > ranks[lower]);
+}
+
+/// stringForContext - Returns a string containing the name of a particular
+///   InstructionContext, usually for diagnostic purposes.
+///
+/// @param insnContext  - The instruction class to transform to a string.
+/// @return           - A statically-allocated string constant that contains the
+///                     name of the instruction class.
+static inline const char* stringForContext(InstructionContext insnContext) {
+  switch (insnContext) {
+  default:
+    llvm_unreachable("Unhandled instruction class");
+#define ENUM_ENTRY(n, r, d)   case n: return #n; break;
+  INSTRUCTION_CONTEXTS
+#undef ENUM_ENTRY
+  }
+
+  return 0;
+}
+
+/// stringForOperandType - Like stringForContext, but for OperandTypes.
+static inline const char* stringForOperandType(OperandType type) {
+  switch (type) {
+  default:
+    llvm_unreachable("Unhandled type");
+#define ENUM_ENTRY(i, d) case i: return #i;
+  TYPES
+#undef ENUM_ENTRY
+  }
+}
+
+/// stringForOperandEncoding - like stringForContext, but for
+///   OperandEncodings.
+static inline const char* stringForOperandEncoding(OperandEncoding encoding) {
+  switch (encoding) {
+  default:
+    llvm_unreachable("Unhandled encoding");
+#define ENUM_ENTRY(i, d) case i: return #i;
+  ENCODINGS
+#undef ENUM_ENTRY
+  }
+}
+
+void DisassemblerTables::emitOneID(raw_ostream &o,
+                                   uint32_t &i,
+                                   InstrUID id,
+                                   bool addComma) const {
+  if (id)
+    o.indent(i * 2) << format("0x%hx", id);
+  else
+    o.indent(i * 2) << 0;
+  
+  if (addComma)
+    o << ", ";
+  else
+    o << "  ";
+  
+  o << "/* ";
+  o << InstructionSpecifiers[id].name;
+  o << "*/";
+  
+  o << "\n";
+}
+
+/// emitEmptyTable - Emits the modRMEmptyTable, which is used as a ID table by
+///   all ModR/M decisions for instructions that are invalid for all possible
+///   ModR/M byte values.
+///
+/// @param o        - The output stream on which to emit the table.
+/// @param i        - The indentation level for that output stream.
+static void emitEmptyTable(raw_ostream &o, uint32_t &i)
+{
+  o.indent(i * 2) << "static InstrUID modRMEmptyTable[1] = { 0 };" << "\n";
+  o << "\n";
+}
+
+/// getDecisionType - Determines whether a ModRM decision with 255 entries can
+///   be compacted by eliminating redundant information.
+///
+/// @param decision - The decision to be compacted.
+/// @return         - The compactest available representation for the decision.
+static ModRMDecisionType getDecisionType(ModRMDecision &decision)
+{
+  bool satisfiesOneEntry = true;
+  bool satisfiesSplitRM = true;
+  
+  uint16_t index;
+  
+  for (index = 0; index < 256; ++index) {
+    if (decision.instructionIDs[index] != decision.instructionIDs[0])
+      satisfiesOneEntry = false;
+    
+    if (((index & 0xc0) == 0xc0) &&
+       (decision.instructionIDs[index] != decision.instructionIDs[0xc0]))
+      satisfiesSplitRM = false;
+    
+    if (((index & 0xc0) != 0xc0) &&
+       (decision.instructionIDs[index] != decision.instructionIDs[0x00]))
+      satisfiesSplitRM = false;
+  }
+  
+  if (satisfiesOneEntry)
+    return MODRM_ONEENTRY;
+  
+  if (satisfiesSplitRM)
+    return MODRM_SPLITRM;
+  
+  return MODRM_FULL;
+}
+
+/// stringForDecisionType - Returns a statically-allocated string corresponding
+///   to a particular decision type.
+///
+/// @param dt - The decision type.
+/// @return   - A pointer to the statically-allocated string (e.g., 
+///             "MODRM_ONEENTRY" for MODRM_ONEENTRY).
+static const char* stringForDecisionType(ModRMDecisionType dt)
+{
+#define ENUM_ENTRY(n) case n: return #n;
+  switch (dt) {
+    default:
+      llvm_unreachable("Unknown decision type");  
+    MODRMTYPES
+  };  
+#undef ENUM_ENTRY
+}
+  
+/// stringForModifierType - Returns a statically-allocated string corresponding
+///   to an opcode modifier type.
+///
+/// @param mt - The modifier type.
+/// @return   - A pointer to the statically-allocated string (e.g.,
+///             "MODIFIER_NONE" for MODIFIER_NONE).
+static const char* stringForModifierType(ModifierType mt)
+{
+#define ENUM_ENTRY(n) case n: return #n;
+  switch(mt) {
+    default:
+      llvm_unreachable("Unknown modifier type");
+    MODIFIER_TYPES
+  };
+#undef ENUM_ENTRY
+}
+  
+DisassemblerTables::DisassemblerTables() {
+  unsigned i;
+  
+  for (i = 0; i < 4; i++) {
+    Tables[i] = new ContextDecision;
+    memset(Tables[i], 0, sizeof(ContextDecision));
+  }
+  
+  HasConflicts = false;
+}
+  
+DisassemblerTables::~DisassemblerTables() {
+  unsigned i;
+  
+  for (i = 0; i < 4; i++)
+    delete Tables[i];
+}
+  
+void DisassemblerTables::emitModRMDecision(raw_ostream &o1,
+                                           raw_ostream &o2,
+                                           uint32_t &i1,
+                                           uint32_t &i2,
+                                           ModRMDecision &decision)
+  const {
+  static uint64_t sTableNumber = 0;
+  uint64_t thisTableNumber = sTableNumber;
+  ModRMDecisionType dt = getDecisionType(decision);
+  uint16_t index;
+  
+  if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0)
+  {
+    o2.indent(i2) << "{ /* ModRMDecision */" << "\n";
+    i2++;
+    
+    o2.indent(i2) << stringForDecisionType(dt) << "," << "\n";
+    o2.indent(i2) << "modRMEmptyTable";
+    
+    i2--;
+    o2.indent(i2) << "}";
+    return;
+  }
+    
+  o1.indent(i1) << "static InstrUID modRMTable" << thisTableNumber;
+    
+  switch (dt) {
+    default:
+      llvm_unreachable("Unknown decision type");
+    case MODRM_ONEENTRY:
+      o1 << "[1]";
+      break;
+    case MODRM_SPLITRM:
+      o1 << "[2]";
+      break;
+    case MODRM_FULL:
+      o1 << "[256]";
+      break;      
+  }
+
+  o1 << " = {" << "\n";
+  i1++;
+    
+  switch (dt) {
+    default:
+      llvm_unreachable("Unknown decision type");
+    case MODRM_ONEENTRY:
+      emitOneID(o1, i1, decision.instructionIDs[0], false);
+      break;
+    case MODRM_SPLITRM:
+      emitOneID(o1, i1, decision.instructionIDs[0x00], true); // mod = 0b00
+      emitOneID(o1, i1, decision.instructionIDs[0xc0], false); // mod = 0b11
+      break;
+    case MODRM_FULL:
+      for (index = 0; index < 256; ++index)
+        emitOneID(o1, i1, decision.instructionIDs[index], index < 255);
+      break;
+  }
+    
+  i1--;
+  o1.indent(i1) << "};" << "\n";
+  o1 << "\n";
+    
+  o2.indent(i2) << "{ /* struct ModRMDecision */" << "\n";
+  i2++;
+    
+  o2.indent(i2) << stringForDecisionType(dt) << "," << "\n";
+  o2.indent(i2) << "modRMTable" << sTableNumber << "\n";
+    
+  i2--;
+  o2.indent(i2) << "}";
+    
+  ++sTableNumber;
+}
+
+void DisassemblerTables::emitOpcodeDecision(
+  raw_ostream &o1,
+  raw_ostream &o2,
+  uint32_t &i1,
+  uint32_t &i2,
+  OpcodeDecision &decision) const {
+  uint16_t index;
+
+  o2.indent(i2) << "{ /* struct OpcodeDecision */" << "\n";
+  i2++;
+  o2.indent(i2) << "{" << "\n";
+  i2++;
+
+  for (index = 0; index < 256; ++index) {
+    o2.indent(i2);
+
+    o2 << "/* 0x" << format("%02hhx", index) << " */" << "\n";
+
+    emitModRMDecision(o1, o2, i1, i2, decision.modRMDecisions[index]);
+
+    if (index <  255)
+      o2 << ",";
+
+    o2 << "\n";
+  }
+
+  i2--;
+  o2.indent(i2) << "}" << "\n";
+  i2--;
+  o2.indent(i2) << "}" << "\n";
+}
+
+void DisassemblerTables::emitContextDecision(
+  raw_ostream &o1,
+  raw_ostream &o2,
+  uint32_t &i1,
+  uint32_t &i2,
+  ContextDecision &decision,
+  const char* name) const {
+  o2.indent(i2) << "struct ContextDecision " << name << " = {" << "\n";
+  i2++;
+  o2.indent(i2) << "{ /* opcodeDecisions */" << "\n";
+  i2++;
+
+  unsigned index;
+
+  for (index = 0; index < IC_max; ++index) {
+    o2.indent(i2) << "/* ";
+    o2 << stringForContext((InstructionContext)index);
+    o2 << " */";
+    o2 << "\n";
+
+    emitOpcodeDecision(o1, o2, i1, i2, decision.opcodeDecisions[index]);
+
+    if (index + 1 < IC_max)
+      o2 << ", ";
+  }
+
+  i2--;
+  o2.indent(i2) << "}" << "\n";
+  i2--;
+  o2.indent(i2) << "};" << "\n";
+}
+
+void DisassemblerTables::emitInstructionInfo(raw_ostream &o, uint32_t &i) 
+  const {
+  o.indent(i * 2) << "struct InstructionSpecifier ";
+  o << INSTRUCTIONS_STR << "[";
+  o << InstructionSpecifiers.size();
+  o << "] = {" << "\n";
+  
+  i++;
+
+  uint16_t numInstructions = InstructionSpecifiers.size();
+  uint16_t index, operandIndex;
+
+  for (index = 0; index < numInstructions; ++index) {
+    o.indent(i * 2) << "{ /* " << index << " */" << "\n";
+    i++;
+    
+    o.indent(i * 2) << 
+      stringForModifierType(InstructionSpecifiers[index].modifierType);
+    o << "," << "\n";
+    
+    o.indent(i * 2) << "0x";
+    o << format("%02hhx", (uint16_t)InstructionSpecifiers[index].modifierBase);
+    o << "," << "\n";
+
+    o.indent(i * 2) << "{" << "\n";
+    i++;
+
+    for (operandIndex = 0; operandIndex < X86_MAX_OPERANDS; ++operandIndex) {
+      o.indent(i * 2) << "{ ";
+      o << stringForOperandEncoding(InstructionSpecifiers[index]
+                                    .operands[operandIndex]
+                                    .encoding);
+      o << ", ";
+      o << stringForOperandType(InstructionSpecifiers[index]
+                                .operands[operandIndex]
+                                .type);
+      o << " }";
+
+      if (operandIndex < X86_MAX_OPERANDS - 1)
+        o << ",";
+
+      o << "\n";
+    }
+
+    i--;
+    o.indent(i * 2) << "}," << "\n";
+    
+    o.indent(i * 2) << "\"" << InstructionSpecifiers[index].name << "\"";
+    o << "\n";
+
+    i--;
+    o.indent(i * 2) << "}";
+
+    if (index + 1 < numInstructions)
+      o << ",";
+
+    o << "\n";
+  }
+
+  i--;
+  o.indent(i * 2) << "};" << "\n";
+}
+
+void DisassemblerTables::emitContextTable(raw_ostream &o, uint32_t &i) const {
+  uint16_t index;
+
+  o.indent(i * 2) << "InstructionContext ";
+  o << CONTEXTS_STR << "[256] = {" << "\n";
+  i++;
+
+  for (index = 0; index < 256; ++index) {
+    o.indent(i * 2);
+
+    if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS))
+      o << "IC_64BIT_REXW_XS";
+    else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XD))
+      o << "IC_64BIT_REXW_XD";
+    else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && 
+             (index & ATTR_OPSIZE))
+      o << "IC_64BIT_REXW_OPSIZE";
+    else if ((index & ATTR_64BIT) && (index & ATTR_XS))
+      o << "IC_64BIT_XS";
+    else if ((index & ATTR_64BIT) && (index & ATTR_XD))
+      o << "IC_64BIT_XD";
+    else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE))
+      o << "IC_64BIT_OPSIZE";
+    else if ((index & ATTR_64BIT) && (index & ATTR_REXW))
+      o << "IC_64BIT_REXW";
+    else if ((index & ATTR_64BIT))
+      o << "IC_64BIT";
+    else if (index & ATTR_XS)
+      o << "IC_XS";
+    else if (index & ATTR_XD)
+      o << "IC_XD";
+    else if (index & ATTR_OPSIZE)
+      o << "IC_OPSIZE";
+    else
+      o << "IC";
+
+    if (index < 255)
+      o << ",";
+    else
+      o << " ";
+
+    o << " /* " << index << " */";
+
+    o << "\n";
+  }
+
+  i--;
+  o.indent(i * 2) << "};" << "\n";
+}
+
+void DisassemblerTables::emitContextDecisions(raw_ostream &o1,
+                                            raw_ostream &o2,
+                                            uint32_t &i1,
+                                            uint32_t &i2)
+  const {
+  emitContextDecision(o1, o2, i1, i2, *Tables[0], ONEBYTE_STR);
+  emitContextDecision(o1, o2, i1, i2, *Tables[1], TWOBYTE_STR);
+  emitContextDecision(o1, o2, i1, i2, *Tables[2], THREEBYTE38_STR);
+  emitContextDecision(o1, o2, i1, i2, *Tables[3], THREEBYTE3A_STR);
+}
+
+void DisassemblerTables::emit(raw_ostream &o) const {
+  uint32_t i1 = 0;
+  uint32_t i2 = 0;
+  
+  std::string s1;
+  std::string s2;
+  
+  raw_string_ostream o1(s1);
+  raw_string_ostream o2(s2);
+  
+  emitInstructionInfo(o, i2);
+  o << "\n";
+
+  emitContextTable(o, i2);
+  o << "\n";
+  
+  emitEmptyTable(o1, i1);
+  emitContextDecisions(o1, o2, i1, i2);
+  
+  o << o1.str();
+  o << "\n";
+  o << o2.str();
+  o << "\n";
+  o << "\n";
+}
+
+void DisassemblerTables::setTableFields(ModRMDecision     &decision,
+                                        const ModRMFilter &filter,
+                                        InstrUID          uid,
+                                        uint8_t           opcode) {
+  unsigned index;
+
+  for (index = 0; index < 256; ++index) {
+    if (filter.accepts(index)) {
+      if (decision.instructionIDs[index] == uid)
+        continue;
+
+      if (decision.instructionIDs[index] != 0) {
+        InstructionSpecifier &newInfo =
+          InstructionSpecifiers[uid];
+        InstructionSpecifier &previousInfo =
+          InstructionSpecifiers[decision.instructionIDs[index]];
+        
+        if(newInfo.filtered)
+          continue; // filtered instructions get lowest priority
+        
+        if(previousInfo.name == "NOOP")
+          continue; // special case for XCHG32ar and NOOP
+
+        if (outranks(previousInfo.insnContext, newInfo.insnContext))
+          continue;
+        
+        if (previousInfo.insnContext == newInfo.insnContext &&
+            !previousInfo.filtered) {
+          errs() << "Error: Primary decode conflict: ";
+          errs() << newInfo.name << " would overwrite " << previousInfo.name;
+          errs() << "\n";
+          errs() << "ModRM   " << index << "\n";
+          errs() << "Opcode  " << (uint16_t)opcode << "\n";
+          errs() << "Context " << stringForContext(newInfo.insnContext) << "\n";
+          HasConflicts = true;
+        }
+      }
+
+      decision.instructionIDs[index] = uid;
+    }
+  }
+}
+
+void DisassemblerTables::setTableFields(OpcodeType          type,
+                                        InstructionContext  insnContext,
+                                        uint8_t             opcode,
+                                        const ModRMFilter   &filter,
+                                        InstrUID            uid) {
+  unsigned index;
+  
+  ContextDecision &decision = *Tables[type];
+
+  for (index = 0; index < IC_max; ++index) {
+    if (inheritsFrom((InstructionContext)index, 
+                     InstructionSpecifiers[uid].insnContext))
+      setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode], 
+                     filter,
+                     uid,
+                     opcode);
+  }
+}
diff --git a/src/LLVM/utils/TableGen/X86DisassemblerTables.h b/src/LLVM/utils/TableGen/X86DisassemblerTables.h
new file mode 100644
index 0000000..08eba01
--- /dev/null
+++ b/src/LLVM/utils/TableGen/X86DisassemblerTables.h
@@ -0,0 +1,291 @@
+//===- X86DisassemblerTables.h - Disassembler tables ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is part of the X86 Disassembler Emitter.
+// It contains the interface of the disassembler tables.
+// Documentation for the disassembler emitter in general can be found in
+//  X86DisasemblerEmitter.h.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef X86DISASSEMBLERTABLES_H
+#define X86DISASSEMBLERTABLES_H
+
+#include "X86DisassemblerShared.h"
+#include "X86ModRMFilters.h"
+
+#include "llvm/Support/raw_ostream.h"
+
+#include <vector>
+
+namespace llvm {
+
+namespace X86Disassembler {
+
+/// DisassemblerTables - Encapsulates all the decode tables being generated by
+///   the table emitter.  Contains functions to populate the tables as well as
+///   to emit them as hierarchical C structures suitable for consumption by the
+///   runtime.
+class DisassemblerTables {
+private:
+  /// The decoder tables.  There is one for each opcode type:
+  /// [0] one-byte opcodes
+  /// [1] two-byte opcodes of the form 0f __
+  /// [2] three-byte opcodes of the form 0f 38 __
+  /// [3] three-byte opcodes of the form 0f 3a __
+  ContextDecision* Tables[4];
+  
+  /// The instruction information table
+  std::vector<InstructionSpecifier> InstructionSpecifiers;
+  
+  /// True if there are primary decode conflicts in the instruction set
+  bool HasConflicts;
+  
+  /// emitOneID - Emits a table entry for a single instruction entry, at the
+  ///   innermost level of the structure hierarchy.  The entry is printed out
+  ///   in the format "nnnn, /* MNEMONIC */" where nnnn is the ID in decimal,
+  ///   the comma is printed if addComma is true, and the menonic is the name
+  ///   of the instruction as listed in the LLVM tables.
+  ///
+  /// @param o        - The output stream to print the entry on.
+  /// @param i        - The indentation level for o.
+  /// @param id       - The unique ID of the instruction to print.
+  /// @param addComma - Whether or not to print a comma after the ID.  True if
+  ///                    additional items will follow.
+  void emitOneID(raw_ostream &o,
+                 uint32_t &i,
+                 InstrUID id,
+                 bool addComma) const;
+  
+  /// emitModRMDecision - Emits a table of entries corresponding to a single
+  ///   ModR/M decision.  Compacts the ModR/M decision if possible.  ModR/M
+  ///   decisions are printed as:
+  ///
+  ///   { /* struct ModRMDecision */
+  ///     TYPE,
+  ///     modRMTablennnn
+  ///   }
+  ///
+  ///   where nnnn is a unique ID for the corresponding table of IDs.
+  ///   TYPE indicates whether the table has one entry that is the same
+  ///   regardless of ModR/M byte, two entries - one for bytes 0x00-0xbf and one
+  ///   for bytes 0xc0-0xff -, or 256 entries, one for each possible byte.  
+  ///   nnnn is the number of a table for looking up these values.  The tables
+  ///   are writen separately so that tables consisting entirely of zeros will
+  ///   not be duplicated.  (These all have the name modRMEmptyTable.)  A table
+  ///   is printed as:
+  ///   
+  ///   InstrUID modRMTablennnn[k] = {
+  ///     nnnn, /* MNEMONIC */
+  ///     ...
+  ///     nnnn /* MNEMONIC */
+  ///   };
+  ///
+  /// @param o1       - The output stream to print the ID table to.
+  /// @param o2       - The output stream to print the decision structure to.
+  /// @param i1       - The indentation level to use with stream o1.
+  /// @param i2       - The indentation level to use with stream o2.
+  /// @param decision - The ModR/M decision to emit.  This decision has 256
+  ///                   entries - emitModRMDecision decides how to compact it.
+  void emitModRMDecision(raw_ostream &o1,
+                         raw_ostream &o2,
+                         uint32_t &i1,
+                         uint32_t &i2,
+                         ModRMDecision &decision) const;
+  
+  /// emitOpcodeDecision - Emits an OpcodeDecision and all its subsidiary ModR/M
+  ///   decisions.  An OpcodeDecision is printed as:
+  ///
+  ///   { /* struct OpcodeDecision */
+  ///     /* 0x00 */
+  ///     { /* struct ModRMDecision */
+  ///       ...
+  ///     }
+  ///     ...
+  ///   }
+  ///
+  ///   where the ModRMDecision structure is printed as described in the
+  ///   documentation for emitModRMDecision().  emitOpcodeDecision() passes on a
+  ///   stream and indent level for the UID tables generated by
+  ///   emitModRMDecision(), but does not use them itself.
+  ///
+  /// @param o1       - The output stream to print the ID tables generated by
+  ///                   emitModRMDecision() to.
+  /// @param o2       - The output stream for the decision structure itself.
+  /// @param i1       - The indent level to use with stream o1.
+  /// @param i2       - The indent level to use with stream o2.
+  /// @param decision - The OpcodeDecision to emit along with its subsidiary
+  ///                    structures.
+  void emitOpcodeDecision(raw_ostream &o1,
+                          raw_ostream &o2,
+                          uint32_t &i1,
+                          uint32_t &i2,
+                          OpcodeDecision &decision) const;
+  
+  /// emitContextDecision - Emits a ContextDecision and all its subsidiary 
+  ///   Opcode and ModRMDecisions.  A ContextDecision is printed as:
+  ///
+  ///   struct ContextDecision NAME = {
+  ///     { /* OpcodeDecisions */
+  ///       /* IC */
+  ///       { /* struct OpcodeDecision */
+  ///         ...
+  ///       },
+  ///       ...
+  ///     }
+  ///   }
+  ///
+  ///   NAME is the name of the ContextDecision (typically one of the four names 
+  ///   ONEBYTE_SYM, TWOBYTE_SYM, THREEBYTE38_SYM, and THREEBYTE3A_SYM from
+  ///   X86DisassemblerDecoderCommon.h).
+  ///   IC is one of the contexts in InstructionContext.  There is an opcode
+  ///   decision for each possible context.
+  ///   The OpcodeDecision structures are printed as described in the
+  ///   documentation for emitOpcodeDecision.
+  ///
+  /// @param o1       - The output stream to print the ID tables generated by
+  ///                   emitModRMDecision() to.
+  /// @param o2       - The output stream to print the decision structure to.
+  /// @param i1       - The indent level to use with stream o1.
+  /// @param i2       - The indent level to use with stream o2.
+  /// @param decision - The ContextDecision to emit along with its subsidiary
+  ///                   structures.
+  /// @param name     - The name for the ContextDecision.
+  void emitContextDecision(raw_ostream &o1,
+                           raw_ostream &o2,
+                           uint32_t &i1,
+                           uint32_t &i2,                           
+                           ContextDecision &decision,
+                           const char* name) const;
+  
+  /// emitInstructionInfo - Prints the instruction specifier table, which has
+  ///   one entry for each instruction, and contains name and operand
+  ///   information.  This table is printed as:
+  ///
+  ///   struct InstructionSpecifier CONTEXTS_SYM[k] = {
+  ///     {
+  ///       /* nnnn */
+  ///       "MNEMONIC",
+  ///       0xnn,
+  ///       {
+  ///         {
+  ///           ENCODING,
+  ///           TYPE
+  ///         },
+  ///         ...
+  ///       }
+  ///     },
+  ///   };
+  ///
+  ///   k is the total number of instructions.
+  ///   nnnn is the ID of the current instruction (0-based).  This table 
+  ///   includes entries for non-instructions like PHINODE.
+  ///   0xnn is the lowest possible opcode for the current instruction, used for
+  ///   AddRegFrm instructions to compute the operand's value.
+  ///   ENCODING and TYPE describe the encoding and type for a single operand.
+  ///
+  /// @param o  - The output stream to which the instruction table should be 
+  ///             written.
+  /// @param i  - The indent level for use with the stream.
+  void emitInstructionInfo(raw_ostream &o, uint32_t &i) const;
+  
+  /// emitContextTable - Prints the table that is used to translate from an
+  ///   instruction attribute mask to an instruction context.  This table is
+  ///   printed as:
+  ///
+  ///   InstructionContext CONTEXTS_STR[256] = {
+  ///     IC, /* 0x00 */
+  ///     ...
+  ///   };
+  ///
+  ///   IC is the context corresponding to the mask 0x00, and there are 256
+  ///   possible masks.
+  ///
+  /// @param o  - The output stream to which the context table should be written.
+  /// @param i  - The indent level for use with the stream.
+  void emitContextTable(raw_ostream &o, uint32_t &i) const;
+  
+  /// emitContextDecisions - Prints all four ContextDecision structures using
+  ///   emitContextDecision().
+  ///
+  /// @param o1 - The output stream to print the ID tables generated by
+  ///             emitModRMDecision() to.
+  /// @param o2 - The output stream to print the decision structures to.
+  /// @param i1 - The indent level to use with stream o1.
+  /// @param i2 - The indent level to use with stream o2.
+  void emitContextDecisions(raw_ostream &o1,
+                            raw_ostream &o2,
+                            uint32_t &i1,
+                            uint32_t &i2) const; 
+
+  /// setTableFields - Uses a ModRMFilter to set the appropriate entries in a
+  ///   ModRMDecision to refer to a particular instruction ID.
+  ///
+  /// @param decision - The ModRMDecision to populate.
+  /// @param filter   - The filter to use in deciding which entries to populate.
+  /// @param uid      - The unique ID to set matching entries to.
+  /// @param opcode   - The opcode of the instruction, for error reporting.
+  void setTableFields(ModRMDecision &decision,
+                      const ModRMFilter &filter,
+                      InstrUID uid,
+                      uint8_t opcode);
+public:
+  /// Constructor - Allocates space for the class decisions and clears them.
+  DisassemblerTables();
+  
+  ~DisassemblerTables();
+  
+  /// emit - Emits the instruction table, context table, and class decisions.
+  ///
+  /// @param o  - The output stream to print the tables to.
+  void emit(raw_ostream &o) const;
+  
+  /// setTableFields - Uses the opcode type, instruction context, opcode, and a
+  ///   ModRMFilter as criteria to set a particular set of entries in the
+  ///   decode tables to point to a specific uid.
+  ///
+  /// @param type         - The opcode type (ONEBYTE, TWOBYTE, etc.)
+  /// @param insnContext  - The context to use (IC, IC_64BIT, etc.)
+  /// @param opcode       - The last byte of the opcode (not counting any escape
+  ///                       or extended opcodes).
+  /// @param filter       - The ModRMFilter that decides which ModR/M byte values
+  ///                       correspond to the desired instruction.
+  /// @param uid          - The unique ID of the instruction.
+  void setTableFields(OpcodeType type,
+                      InstructionContext insnContext,
+                      uint8_t opcode,
+                      const ModRMFilter &filter,
+                      InstrUID uid);  
+  
+  /// specForUID - Returns the instruction specifier for a given unique
+  ///   instruction ID.  Used when resolving collisions.
+  ///
+  /// @param uid  - The unique ID of the instruction.
+  /// @return     - A reference to the instruction specifier. 
+  InstructionSpecifier& specForUID(InstrUID uid) {
+    if (uid >= InstructionSpecifiers.size())
+      InstructionSpecifiers.resize(uid + 1);
+    
+    return InstructionSpecifiers[uid];
+  }
+  
+  // hasConflicts - Reports whether there were primary decode conflicts
+  //   from any instructions added to the tables.
+  // @return  - true if there were; false otherwise.
+  
+  bool hasConflicts() {
+    return HasConflicts;
+  }
+};
+
+} // namespace X86Disassembler
+
+} // namespace llvm
+
+#endif
diff --git a/src/LLVM/utils/TableGen/X86ModRMFilters.h b/src/LLVM/utils/TableGen/X86ModRMFilters.h
new file mode 100644
index 0000000..45cb07a
--- /dev/null
+++ b/src/LLVM/utils/TableGen/X86ModRMFilters.h
@@ -0,0 +1,197 @@
+//===- X86ModRMFilters.h - Disassembler ModR/M filterss ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is part of the X86 Disassembler Emitter.
+// It contains ModR/M filters that determine which values of the ModR/M byte
+//  are valid for a partiuclar instruction.
+// Documentation for the disassembler emitter in general can be found in
+//  X86DisasemblerEmitter.h.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef X86MODRMFILTERS_H
+#define X86MODRMFILTERS_H
+
+#include "llvm/System/DataTypes.h"
+
+namespace llvm {
+
+namespace X86Disassembler {
+
+/// ModRMFilter - Abstract base class for clases that recognize patterns in
+///   ModR/M bytes.
+class ModRMFilter {
+public:
+  /// Destructor    - Override as necessary.
+  virtual ~ModRMFilter() { }
+
+  /// isDumb        - Indicates whether this filter returns the same value for
+  ///                 any value of the ModR/M byte.
+  ///
+  /// @result       - True if the filter returns the same value for any ModR/M
+  ///                 byte; false if not.
+  virtual bool isDumb() const { return false; }
+  
+  /// accepts       - Indicates whether the filter accepts a particular ModR/M
+  ///                 byte value.
+  ///
+  /// @result       - True if the filter accepts the ModR/M byte; false if not.
+  virtual bool accepts(uint8_t modRM) const = 0;
+};
+
+/// DumbFilter - Accepts any ModR/M byte.  Used for instructions that do not
+///   require a ModR/M byte or instructions where the entire ModR/M byte is used
+///   for operands.
+class DumbFilter : public ModRMFilter {
+public:
+  bool isDumb() const {
+    return true;
+  }
+  
+  bool accepts(uint8_t modRM) const {
+    return true;
+  }
+};
+
+/// ModFilter - Filters based on the mod bits [bits 7-6] of the ModR/M byte.
+///   Some instructions are classified based on whether they are 11 or anything
+///   else.  This filter performs that classification.
+class ModFilter : public ModRMFilter {
+private:
+  bool R;
+public:
+  /// Constructor
+  ///
+  /// @r            - True if the mod bits of the ModR/M byte must be 11; false
+  ///                 otherwise.  The name r derives from the fact that the mod
+  ///                 bits indicate whether the R/M bits [bits 2-0] signify a
+  ///                 register or a memory operand.
+  ModFilter(bool r) :
+    ModRMFilter(),
+    R(r) {
+  }
+    
+  bool accepts(uint8_t modRM) const {
+    if (R == ((modRM & 0xc0) == 0xc0))
+      return true;
+    else
+      return false;
+  }
+};
+
+/// EscapeFilter - Filters escape opcodes, which are classified in two ways.  If
+///   the ModR/M byte is between 0xc0 and 0xff, then there is one slot for each
+///   possible value.  Otherwise, there is one instruction for each value of the
+///   nnn field [bits 5-3], known elsewhere as the reg field.
+class EscapeFilter : public ModRMFilter {
+private:
+  bool C0_FF;
+  uint8_t NNN_or_ModRM;
+public:
+  /// Constructor
+  ///
+  /// @c0_ff        - True if the ModR/M byte must fall between 0xc0 and 0xff;
+  ///                 false otherwise.
+  /// @nnn_or_modRM - If c0_ff is true, the required value of the entire ModR/M
+  ///                 byte.  If c0_ff is false, the required value of the nnn
+  ///                 field.
+  EscapeFilter(bool c0_ff, uint8_t nnn_or_modRM) :
+    ModRMFilter(),
+    C0_FF(c0_ff),
+    NNN_or_ModRM(nnn_or_modRM) {
+  }
+    
+  bool accepts(uint8_t modRM) const {
+    if ((C0_FF && modRM >= 0xc0 && (modRM == NNN_or_ModRM)) ||
+        (!C0_FF && modRM < 0xc0  && ((modRM & 0x38) >> 3) == NNN_or_ModRM))
+      return true;
+    else
+      return false;
+  }
+};
+
+/// AddRegEscapeFilter - Some escape opcodes have one of the register operands
+///   added to the ModR/M byte, meaning that a range of eight ModR/M values
+///   maps to a single instruction.  Such instructions require the ModR/M byte
+///   to fall between 0xc0 and 0xff.
+class AddRegEscapeFilter : public ModRMFilter {
+private:
+  uint8_t ModRM;
+public:
+  /// Constructor
+  ///
+  /// @modRM        - The value of the ModR/M byte when the register operand
+  ///                 refers to the first register in the register set.
+  AddRegEscapeFilter(uint8_t modRM) : ModRM(modRM) {
+  }
+  
+  bool accepts(uint8_t modRM) const {
+    if (modRM >= ModRM && modRM < ModRM + 8)
+      return true;
+    else
+      return false;
+  }
+};
+
+/// ExtendedFilter - Extended opcodes are classified based on the value of the
+///   mod field [bits 7-6] and the value of the nnn field [bits 5-3]. 
+class ExtendedFilter : public ModRMFilter {
+private:
+  bool R;
+  uint8_t NNN;
+public:
+  /// Constructor
+  ///
+  /// @r            - True if the mod field must be set to 11; false otherwise.
+  ///                 The name is explained at ModFilter.
+  /// @nnn          - The required value of the nnn field.
+  ExtendedFilter(bool r, uint8_t nnn) : 
+    ModRMFilter(),
+    R(r),
+    NNN(nnn) {
+  }
+    
+  bool accepts(uint8_t modRM) const {
+    if (((R  && ((modRM & 0xc0) == 0xc0)) ||
+        (!R && ((modRM & 0xc0) != 0xc0))) &&
+        (((modRM & 0x38) >> 3) == NNN))
+      return true;
+    else
+      return false;
+  }
+};
+
+/// ExactFilter - The occasional extended opcode (such as VMCALL or MONITOR)
+///   requires the ModR/M byte to have a specific value.
+class ExactFilter : public ModRMFilter
+{
+private:
+  uint8_t ModRM;
+public:
+  /// Constructor
+  ///
+  /// @modRM        - The required value of the full ModR/M byte.
+  ExactFilter(uint8_t modRM) :
+    ModRMFilter(),
+    ModRM(modRM) {
+  }
+    
+  bool accepts(uint8_t modRM) const {
+    if (ModRM == modRM)
+      return true;
+    else
+      return false;
+  }
+};
+
+} // namespace X86Disassembler
+
+} // namespace llvm
+
+#endif
diff --git a/src/LLVM/utils/TableGen/X86RecognizableInstr.cpp b/src/LLVM/utils/TableGen/X86RecognizableInstr.cpp
new file mode 100644
index 0000000..4dba85b
--- /dev/null
+++ b/src/LLVM/utils/TableGen/X86RecognizableInstr.cpp
@@ -0,0 +1,983 @@
+//===- X86RecognizableInstr.cpp - Disassembler instruction spec --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is part of the X86 Disassembler Emitter.
+// It contains the implementation of a single recognizable instruction.
+// Documentation for the disassembler emitter in general can be found in
+//  X86DisasemblerEmitter.h.
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86DisassemblerShared.h"
+#include "X86RecognizableInstr.h"
+#include "X86ModRMFilters.h"
+
+#include "llvm/Support/ErrorHandling.h"
+
+#include <string>
+
+using namespace llvm;
+
+#define MRM_MAPPING     \
+  MAP(C1, 33)           \
+  MAP(C2, 34)           \
+  MAP(C3, 35)           \
+  MAP(C4, 36)           \
+  MAP(C8, 37)           \
+  MAP(C9, 38)           \
+  MAP(E8, 39)           \
+  MAP(F0, 40)           \
+  MAP(F8, 41)           \
+  MAP(F9, 42)
+
+// A clone of X86 since we can't depend on something that is generated.
+namespace X86Local {
+  enum {
+    Pseudo      = 0,
+    RawFrm      = 1,
+    AddRegFrm   = 2,
+    MRMDestReg  = 3,
+    MRMDestMem  = 4,
+    MRMSrcReg   = 5,
+    MRMSrcMem   = 6,
+    MRM0r = 16, MRM1r = 17, MRM2r = 18, MRM3r = 19, 
+    MRM4r = 20, MRM5r = 21, MRM6r = 22, MRM7r = 23,
+    MRM0m = 24, MRM1m = 25, MRM2m = 26, MRM3m = 27,
+    MRM4m = 28, MRM5m = 29, MRM6m = 30, MRM7m = 31,
+    MRMInitReg  = 32,
+    
+#define MAP(from, to) MRM_##from = to,
+    MRM_MAPPING
+#undef MAP
+    lastMRM
+  };
+  
+  enum {
+    TB  = 1,
+    REP = 2,
+    D8 = 3, D9 = 4, DA = 5, DB = 6,
+    DC = 7, DD = 8, DE = 9, DF = 10,
+    XD = 11,  XS = 12,
+    T8 = 13,  P_TA = 14,
+    P_0F_AE = 16, P_0F_01 = 17
+  };
+}
+
+// If rows are added to the opcode extension tables, then corresponding entries
+// must be added here.  
+//
+// If the row corresponds to a single byte (i.e., 8f), then add an entry for
+// that byte to ONE_BYTE_EXTENSION_TABLES.
+//
+// If the row corresponds to two bytes where the first is 0f, add an entry for 
+// the second byte to TWO_BYTE_EXTENSION_TABLES.
+//
+// If the row corresponds to some other set of bytes, you will need to modify
+// the code in RecognizableInstr::emitDecodePath() as well, and add new prefixes
+// to the X86 TD files, except in two cases: if the first two bytes of such a 
+// new combination are 0f 38 or 0f 3a, you just have to add maps called
+// THREE_BYTE_38_EXTENSION_TABLES and THREE_BYTE_3A_EXTENSION_TABLES and add a
+// switch(Opcode) just below the case X86Local::T8: or case X86Local::TA: line
+// in RecognizableInstr::emitDecodePath().
+
+#define ONE_BYTE_EXTENSION_TABLES \
+  EXTENSION_TABLE(80)             \
+  EXTENSION_TABLE(81)             \
+  EXTENSION_TABLE(82)             \
+  EXTENSION_TABLE(83)             \
+  EXTENSION_TABLE(8f)             \
+  EXTENSION_TABLE(c0)             \
+  EXTENSION_TABLE(c1)             \
+  EXTENSION_TABLE(c6)             \
+  EXTENSION_TABLE(c7)             \
+  EXTENSION_TABLE(d0)             \
+  EXTENSION_TABLE(d1)             \
+  EXTENSION_TABLE(d2)             \
+  EXTENSION_TABLE(d3)             \
+  EXTENSION_TABLE(f6)             \
+  EXTENSION_TABLE(f7)             \
+  EXTENSION_TABLE(fe)             \
+  EXTENSION_TABLE(ff)
+  
+#define TWO_BYTE_EXTENSION_TABLES \
+  EXTENSION_TABLE(00)             \
+  EXTENSION_TABLE(01)             \
+  EXTENSION_TABLE(18)             \
+  EXTENSION_TABLE(71)             \
+  EXTENSION_TABLE(72)             \
+  EXTENSION_TABLE(73)             \
+  EXTENSION_TABLE(ae)             \
+  EXTENSION_TABLE(b9)             \
+  EXTENSION_TABLE(ba)             \
+  EXTENSION_TABLE(c7)
+
+using namespace X86Disassembler;
+
+/// needsModRMForDecode - Indicates whether a particular instruction requires a
+///   ModR/M byte for the instruction to be properly decoded.  For example, a 
+///   MRMDestReg instruction needs the Mod field in the ModR/M byte to be set to
+///   0b11.
+///
+/// @param form - The form of the instruction.
+/// @return     - true if the form implies that a ModR/M byte is required, false
+///               otherwise.
+static bool needsModRMForDecode(uint8_t form) {
+  if (form == X86Local::MRMDestReg    ||
+     form == X86Local::MRMDestMem    ||
+     form == X86Local::MRMSrcReg     ||
+     form == X86Local::MRMSrcMem     ||
+     (form >= X86Local::MRM0r && form <= X86Local::MRM7r) ||
+     (form >= X86Local::MRM0m && form <= X86Local::MRM7m))
+    return true;
+  else
+    return false;
+}
+
+/// isRegFormat - Indicates whether a particular form requires the Mod field of
+///   the ModR/M byte to be 0b11.
+///
+/// @param form - The form of the instruction.
+/// @return     - true if the form implies that Mod must be 0b11, false
+///               otherwise.
+static bool isRegFormat(uint8_t form) {
+  if (form == X86Local::MRMDestReg ||
+     form == X86Local::MRMSrcReg  ||
+     (form >= X86Local::MRM0r && form <= X86Local::MRM7r))
+    return true;
+  else
+    return false;
+}
+
+/// byteFromBitsInit - Extracts a value at most 8 bits in width from a BitsInit.
+///   Useful for switch statements and the like.
+///
+/// @param init - A reference to the BitsInit to be decoded.
+/// @return     - The field, with the first bit in the BitsInit as the lowest
+///               order bit.
+static uint8_t byteFromBitsInit(BitsInit &init) {
+  int width = init.getNumBits();
+
+  assert(width <= 8 && "Field is too large for uint8_t!");
+
+  int     index;
+  uint8_t mask = 0x01;
+
+  uint8_t ret = 0;
+
+  for (index = 0; index < width; index++) {
+    if (static_cast<BitInit*>(init.getBit(index))->getValue())
+      ret |= mask;
+
+    mask <<= 1;
+  }
+
+  return ret;
+}
+
+/// byteFromRec - Extract a value at most 8 bits in with from a Record given the
+///   name of the field.
+///
+/// @param rec  - The record from which to extract the value.
+/// @param name - The name of the field in the record.
+/// @return     - The field, as translated by byteFromBitsInit().
+static uint8_t byteFromRec(const Record* rec, const std::string &name) {
+  BitsInit* bits = rec->getValueAsBitsInit(name);
+  return byteFromBitsInit(*bits);
+}
+
+RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
+                                     const CodeGenInstruction &insn,
+                                     InstrUID uid) {
+  UID = uid;
+
+  Rec = insn.TheDef;
+  Name = Rec->getName();
+  Spec = &tables.specForUID(UID);
+  
+  if (!Rec->isSubClassOf("X86Inst")) {
+    ShouldBeEmitted = false;
+    return;
+  }
+  
+  Prefix   = byteFromRec(Rec, "Prefix");
+  Opcode   = byteFromRec(Rec, "Opcode");
+  Form     = byteFromRec(Rec, "FormBits");
+  SegOvr   = byteFromRec(Rec, "SegOvrBits");
+  
+  HasOpSizePrefix  = Rec->getValueAsBit("hasOpSizePrefix");
+  HasREX_WPrefix   = Rec->getValueAsBit("hasREX_WPrefix");
+  HasVEX_4VPrefix  = Rec->getValueAsBit("hasVEX_4VPrefix");
+  HasLockPrefix    = Rec->getValueAsBit("hasLockPrefix");
+  IsCodeGenOnly    = Rec->getValueAsBit("isCodeGenOnly");
+  
+  Name      = Rec->getName();
+  AsmString = Rec->getValueAsString("AsmString");
+  
+  Operands = &insn.OperandList;
+  
+  IsSSE            = HasOpSizePrefix && (Name.find("16") == Name.npos);
+  HasFROperands    = false;
+  
+  ShouldBeEmitted  = true;
+}
+  
+void RecognizableInstr::processInstr(DisassemblerTables &tables,
+                                   const CodeGenInstruction &insn,
+                                   InstrUID uid)
+{
+  // Ignore "asm parser only" instructions.
+  if (insn.TheDef->getValueAsBit("isAsmParserOnly"))
+    return;
+  
+  RecognizableInstr recogInstr(tables, insn, uid);
+  
+  recogInstr.emitInstructionSpecifier(tables);
+  
+  if (recogInstr.shouldBeEmitted())
+    recogInstr.emitDecodePath(tables);
+}
+
+InstructionContext RecognizableInstr::insnContext() const {
+  InstructionContext insnContext;
+
+  if (Name.find("64") != Name.npos || HasREX_WPrefix) {
+    if (HasREX_WPrefix && HasOpSizePrefix)
+      insnContext = IC_64BIT_REXW_OPSIZE;
+    else if (HasOpSizePrefix)
+      insnContext = IC_64BIT_OPSIZE;
+    else if (HasREX_WPrefix && Prefix == X86Local::XS)
+      insnContext = IC_64BIT_REXW_XS;
+    else if (HasREX_WPrefix && Prefix == X86Local::XD)
+      insnContext = IC_64BIT_REXW_XD;
+    else if (Prefix == X86Local::XD)
+      insnContext = IC_64BIT_XD;
+    else if (Prefix == X86Local::XS)
+      insnContext = IC_64BIT_XS;
+    else if (HasREX_WPrefix)
+      insnContext = IC_64BIT_REXW;
+    else
+      insnContext = IC_64BIT;
+  } else {
+    if (HasOpSizePrefix)
+      insnContext = IC_OPSIZE;
+    else if (Prefix == X86Local::XD)
+      insnContext = IC_XD;
+    else if (Prefix == X86Local::XS)
+      insnContext = IC_XS;
+    else
+      insnContext = IC;
+  }
+
+  return insnContext;
+}
+  
+RecognizableInstr::filter_ret RecognizableInstr::filter() const {
+  // Filter out intrinsics
+  
+  if (!Rec->isSubClassOf("X86Inst"))
+    return FILTER_STRONG;
+  
+  if (Form == X86Local::Pseudo ||
+      IsCodeGenOnly)
+    return FILTER_STRONG;
+  
+  if (Form == X86Local::MRMInitReg)
+    return FILTER_STRONG;
+
+  
+  // Filter out instructions with a LOCK prefix;
+  //   prefer forms that do not have the prefix
+  if (HasLockPrefix)
+    return FILTER_WEAK;
+  
+  // Filter out artificial instructions
+
+  if (Name.find("TAILJMP") != Name.npos    ||
+     Name.find("_Int") != Name.npos       ||
+     Name.find("_int") != Name.npos       ||
+     Name.find("Int_") != Name.npos       ||
+     Name.find("_NOREX") != Name.npos     ||
+     Name.find("_TC") != Name.npos     ||
+     Name.find("EH_RETURN") != Name.npos  ||
+     Name.find("V_SET") != Name.npos      ||
+     Name.find("LOCK_") != Name.npos      ||
+     Name.find("WIN") != Name.npos)
+    return FILTER_STRONG;
+
+  // Special cases.
+  
+  if (Name.find("PCMPISTRI") != Name.npos && Name != "PCMPISTRI")
+    return FILTER_WEAK;
+  if (Name.find("PCMPESTRI") != Name.npos && Name != "PCMPESTRI")
+    return FILTER_WEAK;
+
+  if (Name.find("MOV") != Name.npos && Name.find("r0") != Name.npos)
+    return FILTER_WEAK;
+  if (Name.find("MOVZ") != Name.npos && Name.find("MOVZX") == Name.npos)
+    return FILTER_WEAK;
+  if (Name.find("Fs") != Name.npos)
+    return FILTER_WEAK;
+  if (Name == "MOVLPDrr"          ||
+      Name == "MOVLPSrr"          ||
+      Name == "PUSHFQ"            ||
+      Name == "BSF16rr"           ||
+      Name == "BSF16rm"           ||
+      Name == "BSR16rr"           ||
+      Name == "BSR16rm"           ||
+      Name == "MOVSX16rm8"        ||
+      Name == "MOVSX16rr8"        ||
+      Name == "MOVZX16rm8"        ||
+      Name == "MOVZX16rr8"        ||
+      Name == "PUSH32i16"         ||
+      Name == "PUSH64i16"         ||
+      Name == "MOVPQI2QImr"       ||
+      Name == "MOVSDmr"           ||
+      Name == "MOVSDrm"           ||
+      Name == "MOVSSmr"           ||
+      Name == "MOVSSrm"           ||
+      Name == "MMX_MOVD64rrv164"  ||
+      Name == "CRC32m16"          ||
+      Name == "MOV64ri64i32"      ||
+      Name == "CRC32r16")
+    return FILTER_WEAK;
+
+  // Filter out instructions with segment override prefixes.
+  // They're too messy to handle now and we'll special case them if needed.
+
+  if (SegOvr)
+    return FILTER_STRONG;
+  
+  // Filter out instructions that can't be printed.
+
+  if (AsmString.size() == 0)
+    return FILTER_STRONG;
+  
+  // Filter out instructions with subreg operands.
+  
+  if (AsmString.find("subreg") != AsmString.npos)
+    return FILTER_STRONG;
+
+  if (HasFROperands && Name.find("MOV") != Name.npos &&
+     ((Name.find("2") != Name.npos && Name.find("32") == Name.npos) || 
+      (Name.find("to") != Name.npos)))
+    return FILTER_WEAK;
+
+  return FILTER_NORMAL;
+}
+  
+void RecognizableInstr::handleOperand(
+  bool optional,
+  unsigned &operandIndex,
+  unsigned &physicalOperandIndex,
+  unsigned &numPhysicalOperands,
+  unsigned *operandMapping,
+  OperandEncoding (*encodingFromString)(const std::string&, bool hasOpSizePrefix)) {
+  if (optional) {
+    if (physicalOperandIndex >= numPhysicalOperands)
+      return;
+  } else {
+    assert(physicalOperandIndex < numPhysicalOperands);
+  }
+  
+  while (operandMapping[operandIndex] != operandIndex) {
+    Spec->operands[operandIndex].encoding = ENCODING_DUP;
+    Spec->operands[operandIndex].type =
+      (OperandType)(TYPE_DUP0 + operandMapping[operandIndex]);
+    ++operandIndex;
+  }
+  
+  const std::string &typeName = (*Operands)[operandIndex].Rec->getName();
+  
+  Spec->operands[operandIndex].encoding = encodingFromString(typeName,
+                                                              HasOpSizePrefix);
+  Spec->operands[operandIndex].type = typeFromString(typeName, 
+                                                      IsSSE,
+                                                      HasREX_WPrefix,
+                                                      HasOpSizePrefix);
+  
+  ++operandIndex;
+  ++physicalOperandIndex;
+}
+
+void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
+  Spec->name       = Name;
+    
+  if (!Rec->isSubClassOf("X86Inst"))
+    return;
+  
+  switch (filter()) {
+  case FILTER_WEAK:
+    Spec->filtered = true;
+    break;
+  case FILTER_STRONG:
+    ShouldBeEmitted = false;
+    return;
+  case FILTER_NORMAL:
+    break;
+  }
+  
+  Spec->insnContext = insnContext();
+    
+  const std::vector<CodeGenInstruction::OperandInfo> &OperandList = *Operands;
+  
+  unsigned operandIndex;
+  unsigned numOperands = OperandList.size();
+  unsigned numPhysicalOperands = 0;
+  
+  // operandMapping maps from operands in OperandList to their originals.
+  // If operandMapping[i] != i, then the entry is a duplicate.
+  unsigned operandMapping[X86_MAX_OPERANDS];
+  
+  bool hasFROperands = false;
+  
+  assert(numOperands < X86_MAX_OPERANDS && "X86_MAX_OPERANDS is not large enough");
+  
+  for (operandIndex = 0; operandIndex < numOperands; ++operandIndex) {
+    if (OperandList[operandIndex].Constraints.size()) {
+      const CodeGenInstruction::ConstraintInfo &Constraint =
+        OperandList[operandIndex].Constraints[0];
+      if (Constraint.isTied()) {
+        operandMapping[operandIndex] = Constraint.getTiedOperand();
+      } else {
+        ++numPhysicalOperands;
+        operandMapping[operandIndex] = operandIndex;
+      }
+    } else {
+      ++numPhysicalOperands;
+      operandMapping[operandIndex] = operandIndex;
+    }
+
+    const std::string &recName = OperandList[operandIndex].Rec->getName();
+
+    if (recName.find("FR") != recName.npos)
+      hasFROperands = true;
+  }
+  
+  if (hasFROperands && Name.find("MOV") != Name.npos &&
+     ((Name.find("2") != Name.npos && Name.find("32") == Name.npos) ||
+      (Name.find("to") != Name.npos)))
+    ShouldBeEmitted = false;
+  
+  if (!ShouldBeEmitted)
+    return;
+
+#define HANDLE_OPERAND(class)               \
+  handleOperand(false,                      \
+                operandIndex,               \
+                physicalOperandIndex,       \
+                numPhysicalOperands,        \
+                operandMapping,             \
+                class##EncodingFromString);
+  
+#define HANDLE_OPTIONAL(class)              \
+  handleOperand(true,                       \
+                operandIndex,               \
+                physicalOperandIndex,       \
+                numPhysicalOperands,        \
+                operandMapping,             \
+                class##EncodingFromString);
+  
+  // operandIndex should always be < numOperands
+  operandIndex = 0;
+  // physicalOperandIndex should always be < numPhysicalOperands
+  unsigned physicalOperandIndex = 0;
+    
+  switch (Form) {
+  case X86Local::RawFrm:
+    // Operand 1 (optional) is an address or immediate.
+    // Operand 2 (optional) is an immediate.
+    assert(numPhysicalOperands <= 2 && 
+           "Unexpected number of operands for RawFrm");
+    HANDLE_OPTIONAL(relocation)
+    HANDLE_OPTIONAL(immediate)
+    break;
+  case X86Local::AddRegFrm:
+    // Operand 1 is added to the opcode.
+    // Operand 2 (optional) is an address.
+    assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 &&
+           "Unexpected number of operands for AddRegFrm");
+    HANDLE_OPERAND(opcodeModifier)
+    HANDLE_OPTIONAL(relocation)
+    break;
+  case X86Local::MRMDestReg:
+    // Operand 1 is a register operand in the R/M field.
+    // Operand 2 is a register operand in the Reg/Opcode field.
+    // Operand 3 (optional) is an immediate.
+    assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
+           "Unexpected number of operands for MRMDestRegFrm");
+    HANDLE_OPERAND(rmRegister)
+    HANDLE_OPERAND(roRegister)
+    HANDLE_OPTIONAL(immediate)
+    break;
+  case X86Local::MRMDestMem:
+    // Operand 1 is a memory operand (possibly SIB-extended)
+    // Operand 2 is a register operand in the Reg/Opcode field.
+    // Operand 3 (optional) is an immediate.
+    assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
+           "Unexpected number of operands for MRMDestMemFrm");
+    HANDLE_OPERAND(memory)
+    HANDLE_OPERAND(roRegister)
+    HANDLE_OPTIONAL(immediate)
+    break;
+  case X86Local::MRMSrcReg:
+    // Operand 1 is a register operand in the Reg/Opcode field.
+    // Operand 2 is a register operand in the R/M field.
+    // Operand 3 (optional) is an immediate.
+    assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
+           "Unexpected number of operands for MRMSrcRegFrm");
+    HANDLE_OPERAND(roRegister)
+    HANDLE_OPERAND(rmRegister)
+
+    if (HasVEX_4VPrefix)
+      // FIXME: In AVX, the register below becomes the one encoded
+      // in ModRMVEX and the one above the one in the VEX.VVVV field
+      HANDLE_OPTIONAL(rmRegister)
+    else
+      HANDLE_OPTIONAL(immediate)
+    break;
+  case X86Local::MRMSrcMem:
+    // Operand 1 is a register operand in the Reg/Opcode field.
+    // Operand 2 is a memory operand (possibly SIB-extended)
+    // Operand 3 (optional) is an immediate.
+    assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
+           "Unexpected number of operands for MRMSrcMemFrm");
+    HANDLE_OPERAND(roRegister)
+
+    if (HasVEX_4VPrefix)
+      // FIXME: In AVX, the register below becomes the one encoded
+      // in ModRMVEX and the one above the one in the VEX.VVVV field
+      HANDLE_OPTIONAL(rmRegister)
+
+    HANDLE_OPERAND(memory)
+    HANDLE_OPTIONAL(immediate)
+    break;
+  case X86Local::MRM0r:
+  case X86Local::MRM1r:
+  case X86Local::MRM2r:
+  case X86Local::MRM3r:
+  case X86Local::MRM4r:
+  case X86Local::MRM5r:
+  case X86Local::MRM6r:
+  case X86Local::MRM7r:
+    // Operand 1 is a register operand in the R/M field.
+    // Operand 2 (optional) is an immediate or relocation.
+    assert(numPhysicalOperands <= 2 &&
+           "Unexpected number of operands for MRMnRFrm");
+    HANDLE_OPTIONAL(rmRegister)
+    HANDLE_OPTIONAL(relocation)
+    break;
+  case X86Local::MRM0m:
+  case X86Local::MRM1m:
+  case X86Local::MRM2m:
+  case X86Local::MRM3m:
+  case X86Local::MRM4m:
+  case X86Local::MRM5m:
+  case X86Local::MRM6m:
+  case X86Local::MRM7m:
+    // Operand 1 is a memory operand (possibly SIB-extended)
+    // Operand 2 (optional) is an immediate or relocation.
+    assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 &&
+           "Unexpected number of operands for MRMnMFrm");
+    HANDLE_OPERAND(memory)
+    HANDLE_OPTIONAL(relocation)
+    break;
+  case X86Local::MRMInitReg:
+    // Ignored.
+    break;
+  }
+  
+  #undef HANDLE_OPERAND
+  #undef HANDLE_OPTIONAL
+}
+
+void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
+  // Special cases where the LLVM tables are not complete
+
+#define MAP(from, to)                     \
+  case X86Local::MRM_##from:              \
+    filter = new ExactFilter(0x##from);   \
+    break;
+
+  OpcodeType    opcodeType  = (OpcodeType)-1;
+  
+  ModRMFilter*  filter      = NULL; 
+  uint8_t       opcodeToSet = 0;
+
+  switch (Prefix) {
+  // Extended two-byte opcodes can start with f2 0f, f3 0f, or 0f
+  case X86Local::XD:
+  case X86Local::XS:
+  case X86Local::TB:
+    opcodeType = TWOBYTE;
+
+    switch (Opcode) {
+    default:
+      if (needsModRMForDecode(Form))
+        filter = new ModFilter(isRegFormat(Form));
+      else
+        filter = new DumbFilter();
+      break;
+#define EXTENSION_TABLE(n) case 0x##n:
+    TWO_BYTE_EXTENSION_TABLES
+#undef EXTENSION_TABLE
+      switch (Form) {
+      default:
+        llvm_unreachable("Unhandled two-byte extended opcode");
+      case X86Local::MRM0r:
+      case X86Local::MRM1r:
+      case X86Local::MRM2r:
+      case X86Local::MRM3r:
+      case X86Local::MRM4r:
+      case X86Local::MRM5r:
+      case X86Local::MRM6r:
+      case X86Local::MRM7r:
+        filter = new ExtendedFilter(true, Form - X86Local::MRM0r);
+        break;
+      case X86Local::MRM0m:
+      case X86Local::MRM1m:
+      case X86Local::MRM2m:
+      case X86Local::MRM3m:
+      case X86Local::MRM4m:
+      case X86Local::MRM5m:
+      case X86Local::MRM6m:
+      case X86Local::MRM7m:
+        filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
+        break;
+      MRM_MAPPING
+      } // switch (Form)
+      break;
+    } // switch (Opcode)
+    opcodeToSet = Opcode;
+    break;
+  case X86Local::T8:
+    opcodeType = THREEBYTE_38;
+    if (needsModRMForDecode(Form))
+      filter = new ModFilter(isRegFormat(Form));
+    else
+      filter = new DumbFilter();
+    opcodeToSet = Opcode;
+    break;
+  case X86Local::P_TA:
+    opcodeType = THREEBYTE_3A;
+    if (needsModRMForDecode(Form))
+      filter = new ModFilter(isRegFormat(Form));
+    else
+      filter = new DumbFilter();
+    opcodeToSet = Opcode;
+    break;
+  case X86Local::D8:
+  case X86Local::D9:
+  case X86Local::DA:
+  case X86Local::DB:
+  case X86Local::DC:
+  case X86Local::DD:
+  case X86Local::DE:
+  case X86Local::DF:
+    assert(Opcode >= 0xc0 && "Unexpected opcode for an escape opcode");
+    opcodeType = ONEBYTE;
+    if (Form == X86Local::AddRegFrm) {
+      Spec->modifierType = MODIFIER_MODRM;
+      Spec->modifierBase = Opcode;
+      filter = new AddRegEscapeFilter(Opcode);
+    } else {
+      filter = new EscapeFilter(true, Opcode);
+    }
+    opcodeToSet = 0xd8 + (Prefix - X86Local::D8);
+    break;
+  default:
+    opcodeType = ONEBYTE;
+    switch (Opcode) {
+#define EXTENSION_TABLE(n) case 0x##n:
+    ONE_BYTE_EXTENSION_TABLES
+#undef EXTENSION_TABLE
+      switch (Form) {
+      default:
+        llvm_unreachable("Fell through the cracks of a single-byte "
+                         "extended opcode");
+      case X86Local::MRM0r:
+      case X86Local::MRM1r:
+      case X86Local::MRM2r:
+      case X86Local::MRM3r:
+      case X86Local::MRM4r:
+      case X86Local::MRM5r:
+      case X86Local::MRM6r:
+      case X86Local::MRM7r:
+        filter = new ExtendedFilter(true, Form - X86Local::MRM0r);
+        break;
+      case X86Local::MRM0m:
+      case X86Local::MRM1m:
+      case X86Local::MRM2m:
+      case X86Local::MRM3m:
+      case X86Local::MRM4m:
+      case X86Local::MRM5m:
+      case X86Local::MRM6m:
+      case X86Local::MRM7m:
+        filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
+        break;
+      MRM_MAPPING
+      } // switch (Form)
+      break;
+    case 0xd8:
+    case 0xd9:
+    case 0xda:
+    case 0xdb:
+    case 0xdc:
+    case 0xdd:
+    case 0xde:
+    case 0xdf:
+      filter = new EscapeFilter(false, Form - X86Local::MRM0m);
+      break;
+    default:
+      if (needsModRMForDecode(Form))
+        filter = new ModFilter(isRegFormat(Form));
+      else
+        filter = new DumbFilter();
+      break;
+    } // switch (Opcode)
+    opcodeToSet = Opcode;
+  } // switch (Prefix)
+
+  assert(opcodeType != (OpcodeType)-1 &&
+         "Opcode type not set");
+  assert(filter && "Filter not set");
+
+  if (Form == X86Local::AddRegFrm) {
+    if(Spec->modifierType != MODIFIER_MODRM) {
+      assert(opcodeToSet < 0xf9 &&
+             "Not enough room for all ADDREG_FRM operands");
+    
+      uint8_t currentOpcode;
+
+      for (currentOpcode = opcodeToSet;
+           currentOpcode < opcodeToSet + 8;
+           ++currentOpcode)
+        tables.setTableFields(opcodeType, 
+                              insnContext(), 
+                              currentOpcode, 
+                              *filter, 
+                              UID);
+    
+      Spec->modifierType = MODIFIER_OPCODE;
+      Spec->modifierBase = opcodeToSet;
+    } else {
+      // modifierBase was set where MODIFIER_MODRM was set
+      tables.setTableFields(opcodeType, 
+                            insnContext(), 
+                            opcodeToSet, 
+                            *filter, 
+                            UID);
+    }
+  } else {
+    tables.setTableFields(opcodeType,
+                          insnContext(),
+                          opcodeToSet,
+                          *filter,
+                          UID);
+    
+    Spec->modifierType = MODIFIER_NONE;
+    Spec->modifierBase = opcodeToSet;
+  }
+  
+  delete filter;
+  
+#undef MAP
+}
+
+#define TYPE(str, type) if (s == str) return type;
+OperandType RecognizableInstr::typeFromString(const std::string &s,
+                                              bool isSSE,
+                                              bool hasREX_WPrefix,
+                                              bool hasOpSizePrefix) {
+  if (isSSE) {
+    // For SSE instructions, we ignore the OpSize prefix and force operand 
+    // sizes.
+    TYPE("GR16",              TYPE_R16)
+    TYPE("GR32",              TYPE_R32)
+    TYPE("GR64",              TYPE_R64)
+  }
+  if(hasREX_WPrefix) {
+    // For instructions with a REX_W prefix, a declared 32-bit register encoding
+    // is special.
+    TYPE("GR32",              TYPE_R32)
+  }
+  if(!hasOpSizePrefix) {
+    // For instructions without an OpSize prefix, a declared 16-bit register or
+    // immediate encoding is special.
+    TYPE("GR16",              TYPE_R16)
+    TYPE("i16imm",            TYPE_IMM16)
+  }
+  TYPE("i16mem",              TYPE_Mv)
+  TYPE("i16imm",              TYPE_IMMv)
+  TYPE("i16i8imm",            TYPE_IMMv)
+  TYPE("GR16",                TYPE_Rv)
+  TYPE("i32mem",              TYPE_Mv)
+  TYPE("i32imm",              TYPE_IMMv)
+  TYPE("i32i8imm",            TYPE_IMM32)
+  TYPE("GR32",                TYPE_Rv)
+  TYPE("i64mem",              TYPE_Mv)
+  TYPE("i64i32imm",           TYPE_IMM64)
+  TYPE("i64i8imm",            TYPE_IMM64)
+  TYPE("GR64",                TYPE_R64)
+  TYPE("i8mem",               TYPE_M8)
+  TYPE("i8imm",               TYPE_IMM8)
+  TYPE("GR8",                 TYPE_R8)
+  TYPE("VR128",               TYPE_XMM128)
+  TYPE("f128mem",             TYPE_M128)
+  TYPE("FR64",                TYPE_XMM64)
+  TYPE("f64mem",              TYPE_M64FP)
+  TYPE("FR32",                TYPE_XMM32)
+  TYPE("f32mem",              TYPE_M32FP)
+  TYPE("RST",                 TYPE_ST)
+  TYPE("i128mem",             TYPE_M128)
+  TYPE("i64i32imm_pcrel",     TYPE_REL64)
+  TYPE("i16imm_pcrel",        TYPE_REL16)
+  TYPE("i32imm_pcrel",        TYPE_REL32)
+  TYPE("SSECC",               TYPE_IMM3)
+  TYPE("brtarget",            TYPE_RELv)
+  TYPE("brtarget8",           TYPE_REL8)
+  TYPE("f80mem",              TYPE_M80FP)
+  TYPE("lea32mem",            TYPE_LEA)
+  TYPE("lea64_32mem",         TYPE_LEA)
+  TYPE("lea64mem",            TYPE_LEA)
+  TYPE("VR64",                TYPE_MM64)
+  TYPE("i64imm",              TYPE_IMMv)
+  TYPE("opaque32mem",         TYPE_M1616)
+  TYPE("opaque48mem",         TYPE_M1632)
+  TYPE("opaque80mem",         TYPE_M1664)
+  TYPE("opaque512mem",        TYPE_M512)
+  TYPE("SEGMENT_REG",         TYPE_SEGMENTREG)
+  TYPE("DEBUG_REG",           TYPE_DEBUGREG)
+  TYPE("CONTROL_REG",         TYPE_CONTROLREG)
+  TYPE("offset8",             TYPE_MOFFS8)
+  TYPE("offset16",            TYPE_MOFFS16)
+  TYPE("offset32",            TYPE_MOFFS32)
+  TYPE("offset64",            TYPE_MOFFS64)
+  errs() << "Unhandled type string " << s << "\n";
+  llvm_unreachable("Unhandled type string");
+}
+#undef TYPE
+
+#define ENCODING(str, encoding) if (s == str) return encoding;
+OperandEncoding RecognizableInstr::immediateEncodingFromString
+  (const std::string &s,
+   bool hasOpSizePrefix) {
+  if(!hasOpSizePrefix) {
+    // For instructions without an OpSize prefix, a declared 16-bit register or
+    // immediate encoding is special.
+    ENCODING("i16imm",        ENCODING_IW)
+  }
+  ENCODING("i32i8imm",        ENCODING_IB)
+  ENCODING("SSECC",           ENCODING_IB)
+  ENCODING("i16imm",          ENCODING_Iv)
+  ENCODING("i16i8imm",        ENCODING_IB)
+  ENCODING("i32imm",          ENCODING_Iv)
+  ENCODING("i64i32imm",       ENCODING_ID)
+  ENCODING("i64i8imm",        ENCODING_IB)
+  ENCODING("i8imm",           ENCODING_IB)
+  errs() << "Unhandled immediate encoding " << s << "\n";
+  llvm_unreachable("Unhandled immediate encoding");
+}
+
+OperandEncoding RecognizableInstr::rmRegisterEncodingFromString
+  (const std::string &s,
+   bool hasOpSizePrefix) {
+  ENCODING("GR16",            ENCODING_RM)
+  ENCODING("GR32",            ENCODING_RM)
+  ENCODING("GR64",            ENCODING_RM)
+  ENCODING("GR8",             ENCODING_RM)
+  ENCODING("VR128",           ENCODING_RM)
+  ENCODING("FR64",            ENCODING_RM)
+  ENCODING("FR32",            ENCODING_RM)
+  ENCODING("VR64",            ENCODING_RM)
+  errs() << "Unhandled R/M register encoding " << s << "\n";
+  llvm_unreachable("Unhandled R/M register encoding");
+}
+
+OperandEncoding RecognizableInstr::roRegisterEncodingFromString
+  (const std::string &s,
+   bool hasOpSizePrefix) {
+  ENCODING("GR16",            ENCODING_REG)
+  ENCODING("GR32",            ENCODING_REG)
+  ENCODING("GR64",            ENCODING_REG)
+  ENCODING("GR8",             ENCODING_REG)
+  ENCODING("VR128",           ENCODING_REG)
+  ENCODING("FR64",            ENCODING_REG)
+  ENCODING("FR32",            ENCODING_REG)
+  ENCODING("VR64",            ENCODING_REG)
+  ENCODING("SEGMENT_REG",     ENCODING_REG)
+  ENCODING("DEBUG_REG",       ENCODING_REG)
+  ENCODING("CONTROL_REG",     ENCODING_REG)
+  errs() << "Unhandled reg/opcode register encoding " << s << "\n";
+  llvm_unreachable("Unhandled reg/opcode register encoding");
+}
+
+OperandEncoding RecognizableInstr::memoryEncodingFromString
+  (const std::string &s,
+   bool hasOpSizePrefix) {
+  ENCODING("i16mem",          ENCODING_RM)
+  ENCODING("i32mem",          ENCODING_RM)
+  ENCODING("i64mem",          ENCODING_RM)
+  ENCODING("i8mem",           ENCODING_RM)
+  ENCODING("f128mem",         ENCODING_RM)
+  ENCODING("f64mem",          ENCODING_RM)
+  ENCODING("f32mem",          ENCODING_RM)
+  ENCODING("i128mem",         ENCODING_RM)
+  ENCODING("f80mem",          ENCODING_RM)
+  ENCODING("lea32mem",        ENCODING_RM)
+  ENCODING("lea64_32mem",     ENCODING_RM)
+  ENCODING("lea64mem",        ENCODING_RM)
+  ENCODING("opaque32mem",     ENCODING_RM)
+  ENCODING("opaque48mem",     ENCODING_RM)
+  ENCODING("opaque80mem",     ENCODING_RM)
+  ENCODING("opaque512mem",    ENCODING_RM)
+  errs() << "Unhandled memory encoding " << s << "\n";
+  llvm_unreachable("Unhandled memory encoding");
+}
+
+OperandEncoding RecognizableInstr::relocationEncodingFromString
+  (const std::string &s,
+   bool hasOpSizePrefix) {
+  if(!hasOpSizePrefix) {
+    // For instructions without an OpSize prefix, a declared 16-bit register or
+    // immediate encoding is special.
+    ENCODING("i16imm",        ENCODING_IW)
+  }
+  ENCODING("i16imm",          ENCODING_Iv)
+  ENCODING("i16i8imm",        ENCODING_IB)
+  ENCODING("i32imm",          ENCODING_Iv)
+  ENCODING("i32i8imm",        ENCODING_IB)
+  ENCODING("i64i32imm",       ENCODING_ID)
+  ENCODING("i64i8imm",        ENCODING_IB)
+  ENCODING("i8imm",           ENCODING_IB)
+  ENCODING("i64i32imm_pcrel", ENCODING_ID)
+  ENCODING("i16imm_pcrel",    ENCODING_IW)
+  ENCODING("i32imm_pcrel",    ENCODING_ID)
+  ENCODING("brtarget",        ENCODING_Iv)
+  ENCODING("brtarget8",       ENCODING_IB)
+  ENCODING("i64imm",          ENCODING_IO)
+  ENCODING("offset8",         ENCODING_Ia)
+  ENCODING("offset16",        ENCODING_Ia)
+  ENCODING("offset32",        ENCODING_Ia)
+  ENCODING("offset64",        ENCODING_Ia)
+  errs() << "Unhandled relocation encoding " << s << "\n";
+  llvm_unreachable("Unhandled relocation encoding");
+}
+
+OperandEncoding RecognizableInstr::opcodeModifierEncodingFromString
+  (const std::string &s,
+   bool hasOpSizePrefix) {
+  ENCODING("RST",             ENCODING_I)
+  ENCODING("GR32",            ENCODING_Rv)
+  ENCODING("GR64",            ENCODING_RO)
+  ENCODING("GR16",            ENCODING_Rv)
+  ENCODING("GR8",             ENCODING_RB)
+  errs() << "Unhandled opcode modifier encoding " << s << "\n";
+  llvm_unreachable("Unhandled opcode modifier encoding");
+}
+#undef ENCODING
diff --git a/src/LLVM/utils/TableGen/X86RecognizableInstr.h b/src/LLVM/utils/TableGen/X86RecognizableInstr.h
new file mode 100644
index 0000000..db4d96d
--- /dev/null
+++ b/src/LLVM/utils/TableGen/X86RecognizableInstr.h
@@ -0,0 +1,239 @@
+//===- X86RecognizableInstr.h - Disassembler instruction spec ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is part of the X86 Disassembler Emitter.
+// It contains the interface of a single recognizable instruction.
+// Documentation for the disassembler emitter in general can be found in
+//  X86DisasemblerEmitter.h.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef X86RECOGNIZABLEINSTR_H
+#define X86RECOGNIZABLEINSTR_H
+
+#include "X86DisassemblerTables.h"
+
+#include "CodeGenTarget.h"
+#include "Record.h"
+
+#include "llvm/System/DataTypes.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+
+namespace X86Disassembler {
+
+/// RecognizableInstr - Encapsulates all information required to decode a single
+///   instruction, as extracted from the LLVM instruction tables.  Has methods
+///   to interpret the information available in the LLVM tables, and to emit the
+///   instruction into DisassemblerTables.
+class RecognizableInstr {
+private:
+  /// The opcode of the instruction, as used in an MCInst
+  InstrUID UID;
+  /// The record from the .td files corresponding to this instruction
+  const Record* Rec;
+  /// The prefix field from the record
+  uint8_t Prefix;
+  /// The opcode field from the record; this is the opcode used in the Intel
+  /// encoding and therefore distinct from the UID
+  uint8_t Opcode;
+  /// The form field from the record
+  uint8_t Form;
+  /// The segment override field from the record
+  uint8_t SegOvr;
+  /// The hasOpSizePrefix field from the record
+  bool HasOpSizePrefix;
+  /// The hasREX_WPrefix field from the record
+  bool HasREX_WPrefix;
+  /// The hasVEX_4VPrefix field from the record
+  bool HasVEX_4VPrefix;
+  /// The hasLockPrefix field from the record
+  bool HasLockPrefix;
+  /// The isCodeGenOnly filed from the record
+  bool IsCodeGenOnly;
+  
+  /// The instruction name as listed in the tables
+  std::string Name;
+  /// The AT&T AsmString for the instruction
+  std::string AsmString;
+  
+  /// Indicates whether the instruction is SSE
+  bool IsSSE;
+  /// Indicates whether the instruction has FR operands - MOVs with FR operands
+  /// are typically ignored
+  bool HasFROperands;
+  /// Indicates whether the instruction should be emitted into the decode
+  /// tables; regardless, it will be emitted into the instruction info table
+  bool ShouldBeEmitted;
+  
+  /// The operands of the instruction, as listed in the CodeGenInstruction.
+  /// They are not one-to-one with operands listed in the MCInst; for example,
+  /// memory operands expand to 5 operands in the MCInst
+  const std::vector<CodeGenInstruction::OperandInfo>* Operands;
+  /// The description of the instruction that is emitted into the instruction
+  /// info table
+  InstructionSpecifier* Spec;
+
+  /// insnContext - Returns the primary context in which the instruction is
+  ///   valid.
+  ///
+  /// @return - The context in which the instruction is valid.
+  InstructionContext insnContext() const;
+  
+  enum filter_ret {
+    FILTER_STRONG,    // instruction has no place in the instruction tables
+    FILTER_WEAK,      // instruction may conflict, and should be eliminated if
+                      // it does
+    FILTER_NORMAL     // instruction should have high priority and generate an
+                      // error if it conflcits with any other FILTER_NORMAL
+                      // instruction
+  };
+  
+  /// filter - Determines whether the instruction should be decodable.  Some 
+  ///   instructions are pure intrinsics and use unencodable operands; many
+  ///   synthetic instructions are duplicates of other instructions; other
+  ///   instructions only differ in the logical way in which they are used, and
+  ///   have the same decoding.  Because these would cause decode conflicts,
+  ///   they must be filtered out.
+  ///
+  /// @return - The degree of filtering to be applied (see filter_ret).
+  filter_ret filter() const;
+  
+  /// typeFromString - Translates an operand type from the string provided in
+  ///   the LLVM tables to an OperandType for use in the operand specifier.
+  ///
+  /// @param s              - The string, as extracted by calling Rec->getName()
+  ///                         on a CodeGenInstruction::OperandInfo.
+  /// @param isSSE          - Indicates whether the instruction is an SSE 
+  ///                         instruction.  For SSE instructions, immediates are 
+  ///                         fixed-size rather than being affected by the
+  ///                         mandatory OpSize prefix.
+  /// @param hasREX_WPrefix - Indicates whether the instruction has a REX.W
+  ///                         prefix.  If it does, 32-bit register operands stay
+  ///                         32-bit regardless of the operand size.
+  /// @param hasOpSizePrefix- Indicates whether the instruction has an OpSize
+  ///                         prefix.  If it does not, then 16-bit register
+  ///                         operands stay 16-bit.
+  /// @return               - The operand's type.
+  static OperandType typeFromString(const std::string& s, 
+                                    bool isSSE,
+                                    bool hasREX_WPrefix,
+                                    bool hasOpSizePrefix);
+  
+  /// immediateEncodingFromString - Translates an immediate encoding from the
+  ///   string provided in the LLVM tables to an OperandEncoding for use in
+  ///   the operand specifier.
+  ///
+  /// @param s                - See typeFromString().
+  /// @param hasOpSizePrefix  - Indicates whether the instruction has an OpSize
+  ///                           prefix.  If it does not, then 16-bit immediate
+  ///                           operands stay 16-bit.
+  /// @return                 - The operand's encoding.
+  static OperandEncoding immediateEncodingFromString(const std::string &s,
+                                                     bool hasOpSizePrefix);
+  
+  /// rmRegisterEncodingFromString - Like immediateEncodingFromString, but
+  ///   handles operands that are in the REG field of the ModR/M byte.
+  static OperandEncoding rmRegisterEncodingFromString(const std::string &s,
+                                                      bool hasOpSizePrefix);
+  
+  /// rmRegisterEncodingFromString - Like immediateEncodingFromString, but
+  ///   handles operands that are in the REG field of the ModR/M byte.
+  static OperandEncoding roRegisterEncodingFromString(const std::string &s,
+                                                      bool hasOpSizePrefix);
+  static OperandEncoding memoryEncodingFromString(const std::string &s,
+                                                  bool hasOpSizePrefix);
+  static OperandEncoding relocationEncodingFromString(const std::string &s,
+                                                      bool hasOpSizePrefix);
+  static OperandEncoding opcodeModifierEncodingFromString(const std::string &s,
+                                                          bool hasOpSizePrefix);
+  
+  /// handleOperand - Converts a single operand from the LLVM table format to
+  ///   the emitted table format, handling any duplicate operands it encounters
+  ///   and then one non-duplicate.
+  ///
+  /// @param optional             - Determines whether to assert that the
+  ///                               operand exists.
+  /// @param operandIndex         - The index into the generated operand table.
+  ///                               Incremented by this function one or more
+  ///                               times to reflect possible duplicate 
+  ///                               operands).
+  /// @param physicalOperandIndex - The index of the current operand into the
+  ///                               set of non-duplicate ('physical') operands.
+  ///                               Incremented by this function once.
+  /// @param numPhysicalOperands  - The number of non-duplicate operands in the
+  ///                               instructions.
+  /// @param operandMapping       - The operand mapping, which has an entry for
+  ///                               each operand that indicates whether it is a
+  ///                               duplicate, and of what.
+  void handleOperand(bool optional,
+                     unsigned &operandIndex,
+                     unsigned &physicalOperandIndex,
+                     unsigned &numPhysicalOperands,
+                     unsigned *operandMapping,
+                     OperandEncoding (*encodingFromString)
+                       (const std::string&,
+                        bool hasOpSizePrefix));
+  
+  /// shouldBeEmitted - Returns the shouldBeEmitted field.  Although filter()
+  ///   filters out many instructions, at various points in decoding we
+  ///   determine that the instruction should not actually be decodable.  In
+  ///   particular, MMX MOV instructions aren't emitted, but they're only
+  ///   identified during operand parsing.
+  ///
+  /// @return - true if at this point we believe the instruction should be
+  ///   emitted; false if not.  This will return false if filter() returns false
+  ///   once emitInstructionSpecifier() has been called.
+  bool shouldBeEmitted() const {
+    return ShouldBeEmitted;
+  }
+  
+  /// emitInstructionSpecifier - Loads the instruction specifier for the current
+  ///   instruction into a DisassemblerTables.
+  ///
+  /// @arg tables - The DisassemblerTables to populate with the specifier for
+  ///               the current instruction.
+  void emitInstructionSpecifier(DisassemblerTables &tables);
+  
+  /// emitDecodePath - Populates the proper fields in the decode tables
+  ///   corresponding to the decode paths for this instruction.
+  ///
+  /// @arg tables - The DisassemblerTables to populate with the decode
+  ///               decode information for the current instruction.
+  void emitDecodePath(DisassemblerTables &tables) const;
+
+  /// Constructor - Initializes a RecognizableInstr with the appropriate fields
+  ///   from a CodeGenInstruction.
+  ///
+  /// @arg tables - The DisassemblerTables that the specifier will be added to.
+  /// @arg insn   - The CodeGenInstruction to extract information from.
+  /// @arg uid    - The unique ID of the current instruction.
+  RecognizableInstr(DisassemblerTables &tables,
+                    const CodeGenInstruction &insn,
+                    InstrUID uid);
+public:
+  /// processInstr - Accepts a CodeGenInstruction and loads decode information
+  ///   for it into a DisassemblerTables if appropriate.
+  ///
+  /// @arg tables - The DiassemblerTables to be populated with decode
+  ///               information.
+  /// @arg insn   - The CodeGenInstruction to be used as a source for this
+  ///               information.
+  /// @uid        - The unique ID of the instruction.
+  static void processInstr(DisassemblerTables &tables,
+                           const CodeGenInstruction &insn,
+                           InstrUID uid);
+};
+  
+} // namespace X86Disassembler
+
+} // namespace llvm
+
+#endif
diff --git a/src/LLVM/utils/UpdateCMakeLists.pl b/src/LLVM/utils/UpdateCMakeLists.pl
new file mode 100644
index 0000000..8f53514
--- /dev/null
+++ b/src/LLVM/utils/UpdateCMakeLists.pl
@@ -0,0 +1,119 @@
+#!/usr/bin/env perl
+use strict;
+use File::Find;
+use File::Copy;
+use Digest::MD5;
+
+my @fileTypes = ("cpp", "c");
+my %dirFiles;
+my %dirCMake;
+
+sub GetFiles {
+  my $dir = shift;
+  my $x = $dirFiles{$dir};  
+  if (!defined $x) {
+    $x = [];
+    $dirFiles{$dir} = $x;
+  }  
+  return $x;
+}
+
+sub ProcessFile {
+  my $file = $_;
+  my $dir = $File::Find::dir;
+  # Record if a CMake file was found.
+  if ($file eq "CMakeLists.txt") {
+    $dirCMake{$dir} = $File::Find::name;
+    return 0;
+  }
+  # Grab the extension of the file.
+  $file =~ /\.([^.]+)$/;
+  my $ext = $1;
+  my $files;
+  foreach my $x (@fileTypes) {
+    if ($ext eq $x) {
+      if (!defined $files) {
+        $files = GetFiles($dir);
+      }
+      push @$files, $file;
+      return 0;
+    }
+  }
+  return 0;
+}
+
+sub EmitCMakeList {
+  my $dir = shift;
+  my $files = $dirFiles{$dir};
+  
+  if (!defined $files) {
+    return;
+  }
+  
+  foreach my $file (sort @$files) {
+    print OUT "  ";
+    print OUT $file;
+    print OUT "\n";
+  }  
+}
+
+sub UpdateCMake {
+  my $cmakeList = shift;
+  my $dir = shift;
+  my $cmakeListNew = $cmakeList . ".new";
+  open(IN, $cmakeList);
+  open(OUT, ">", $cmakeListNew);
+  my $foundLibrary = 0;
+  
+  while(<IN>) {
+    if (!$foundLibrary) {
+      print OUT $_;
+      if (/^add_clang_library\(/ || /^add_llvm_library\(/ || /^add_llvm_target\(/
+          || /^add_executable\(/) {
+        $foundLibrary = 1;
+        EmitCMakeList($dir);
+      }
+    }
+    else {
+      if (/\)/) {
+        print OUT $_;
+        $foundLibrary = 0;
+      }
+    }
+  }
+
+  close(IN);
+  close(OUT);
+
+  open(FILE, $cmakeList) or
+    die("Cannot open $cmakeList when computing digest\n");
+  binmode FILE;
+  my $digestA = Digest::MD5->new->addfile(*FILE)->hexdigest;
+  close(FILE);
+    
+  open(FILE, $cmakeListNew) or
+    die("Cannot open $cmakeListNew when computing digest\n");
+  binmode FILE;
+  my $digestB = Digest::MD5->new->addfile(*FILE)->hexdigest;
+  close(FILE);
+  
+  if ($digestA ne $digestB) {
+    move($cmakeListNew, $cmakeList);
+    return 1;    
+  }
+  
+  unlink($cmakeListNew);
+  return 0;
+}
+
+sub UpdateCMakeFiles {
+  foreach my $dir (sort keys %dirCMake) {
+    if (UpdateCMake($dirCMake{$dir}, $dir)) {
+      print "Updated: $dir\n";
+    }
+  }
+}
+
+find({ wanted => \&ProcessFile, follow => 1 }, '.');
+UpdateCMakeFiles();
+
diff --git a/src/LLVM/utils/bugpoint/RemoteRunSafely.sh b/src/LLVM/utils/bugpoint/RemoteRunSafely.sh
new file mode 100644
index 0000000..f390e33
--- /dev/null
+++ b/src/LLVM/utils/bugpoint/RemoteRunSafely.sh
@@ -0,0 +1,105 @@
+#!/bin/sh
+#
+# Program:  RemoteRunSafely.sh
+#
+# Synopsis: This script simply runs another program remotely using ssh.
+#           It always returns the another program exit code or exit with
+#           code 255 which indicates that the program could not be executed.
+#
+# Syntax: 
+#
+#   RemoteRunSafely.sh <hostname> [-l <login_name>] [-p <port>]
+#                <program> <args...>
+#
+#   where:
+#     <hostname>    is the remote host to execute the program,
+#     <login_name>  is the username on the remote host,
+#     <port>        is the port used by the remote client,
+#     <program>     is the path to the program to run,
+#     <args...>     are the arguments to pass to the program.
+#
+
+printUsageAndExit()
+{
+  echo "Usage:"
+  echo "./RemoteRunSafely.sh <hostname> [-l <login_name>] [-p <port>] " \
+       "<program> <args...>"
+  exit 255
+}
+
+moreArgsExpected()
+{
+  # $1 - remaining number of arguments
+  # $2 - number of arguments to shift
+  if [ $1 -lt $2 ]
+  then
+    echo "Error: Wrong number of argumants."
+    printUsageAndExit
+  fi
+}
+
+# Save a copy of the original arguments in a string before we
+# clobber them with the shift command.
+ORIG_ARGS="$*"
+#DEBUG: echo 'GOT: '$ORIG_ARGS
+
+moreArgsExpected $# 1
+RHOST=$1
+shift 1
+
+RUSER=`id -un`
+RCLIENT=ssh
+RPORT=
+WORKING_DIR=
+
+moreArgsExpected $# 1
+if [ $1 = "-l" ]; then
+  moreArgsExpected $# 2
+  RUSER=$2
+  shift 2
+fi
+moreArgsExpected $# 1
+if [ $1 = "-p" ]; then
+  moreArgsExpected $# 2
+  RPORT="-p $2"
+  shift 2
+fi
+
+moreArgsExpected $# 1
+PROGRAM=$(basename $1)
+WORKING_DIR=$(dirname $1)
+shift 1
+
+#DEBUG: echo 'DIR='${0%%`basename $0`}
+#DEBUG: echo 'RHOST='$RHOST
+#DEBUG: echo 'RUSER='$RUSER
+#DEBUG: echo 'PROGRAM='$PROGRAM
+#DEBUG: echo 'WORKING_DIR='$WORKING_DIR
+#DEBUG: echo 'ARGS='$*
+
+# Sanity check
+if [ "$RHOST" = "" -o "$PROGRAM" = "" ]; then
+  printUsageAndExit
+fi
+
+# Local program file must exist and be execuatble
+local_program=$WORKING_DIR"/"$PROGRAM
+if [ ! -x "$local_program" ]; then
+  echo "File "$local_program" does not exist or is not an executable.."
+  exit 255
+fi
+
+connection=$RUSER'@'$RHOST
+remote="./"$PROGRAM
+(
+  cat $local_program |        \
+  $RCLIENT $connection $RPORT \
+   'rm -f '$remote' ; '       \
+   'cat > '$remote' ; chmod +x '$remote' ; '$remote' '$*' ; ' \
+   'err=$? ; rm -f '$remote' ; exit $err'
+)
+err=$?
+
+#DEBUG: echo script exit $err
+exit $err
+
diff --git a/src/LLVM/utils/buildit/GNUmakefile b/src/LLVM/utils/buildit/GNUmakefile
new file mode 100644
index 0000000..08904e6
--- /dev/null
+++ b/src/LLVM/utils/buildit/GNUmakefile
@@ -0,0 +1,131 @@
+# LLVM LOCAL file build machinery
+# LLVM Compiler Makefile for use by buildit.  
+#
+# This makefile is intended only for use with B&I buildit. For "normal" builds
+# use the conventional top-level makefile.
+#
+# You can specify TARGETS=ppc (or i386) on the buildit command line to limit the
+# build to just one target. The default is for ppc and i386. The compiler
+# targetted at this host gets built anyway, but not installed unless it's listed
+# in TARGETS.
+
+# Include the set of standard Apple makefile definitions.
+ifndef CoreOSMakefiles
+CoreOSMakefiles = $(MAKEFILEPATH)/CoreOS
+endif
+include $(CoreOSMakefiles)/Standard/Standard.make
+
+# Enable Apple extensions to (gnu)make.
+USE_APPLE_PB_SUPPORT = all
+
+RC_ARCHS := ppc i386
+HOSTS = $(RC_ARCHS)
+targets = echo $(RC_ARCHS)
+TARGETS := $(shell $(targets))
+
+SRCROOT = .
+
+SRC = $(shell cd $(SRCROOT) && pwd | sed s,/private,,)
+OBJROOT = $(SRC)/obj
+SYMROOT = $(OBJROOT)/../sym
+DSTROOT = $(OBJROOT)/../dst
+
+#######################################################################
+
+PREFIX = /Developer/usr/local
+
+# Unless assertions are forced on in the GMAKE command line, disable them.
+ifndef ENABLE_ASSERTIONS
+ENABLE_ASSERTIONS := no
+endif
+
+# Default is optimized build.
+ifeq ($(LLVM_DEBUG),1)
+LLVM_OPTIMIZED := no
+else
+LLVM_OPTIMIZED := yes
+endif
+
+# Default to not install libLTO.dylib.
+INSTALL_LIBLTO := no
+
+# Default to do a native build, not a cross-build for an ARM host or simulator.
+ARM_HOSTED_BUILD := no
+IOS_SIM_BUILD := no
+
+ifndef RC_ProjectSourceVersion
+RC_ProjectSourceVersion = 9999
+endif
+
+ifndef RC_ProjectSourceSubversion
+RC_ProjectSourceSubversion = 0
+endif
+
+# NOTE : Always put version numbers at the end because they are optional.
+install: $(OBJROOT) $(SYMROOT) $(DSTROOT)
+	cd $(OBJROOT) && \
+	  $(SRC)/utils/buildit/build_llvm "$(RC_ARCHS)" "$(TARGETS)" \
+	    $(SRC) $(PREFIX) $(DSTROOT) $(SYMROOT) \
+	    $(ENABLE_ASSERTIONS) $(LLVM_OPTIMIZED) $(INSTALL_LIBLTO) \
+	    $(ARM_HOSTED_BUILD) $(IOS_SIM_BUILD) \
+	    $(RC_ProjectSourceVersion) $(RC_ProjectSourceSubversion) 
+
+EmbeddedHosted:
+	$(MAKE) ARM_HOSTED_BUILD=yes PREFIX=/usr install
+
+# When building for the iOS simulator, MACOSX_DEPLOYMENT_TARGET is not set
+# by default, but it needs to be set when building tools that run on the host
+# (e.g., tblgen), so set it here.
+EmbeddedSim:
+	export MACOSX_DEPLOYMENT_TARGET=`sw_vers -productVersion`; \
+	$(MAKE) IOS_SIM_BUILD=yes PREFIX=$(SDKROOT)/usr install
+
+# installhdrs does nothing, because the headers aren't useful until
+# the compiler is installed.
+installhdrs:
+
+# We build and install in one shell script.
+build: 
+
+installsrc:
+	@echo
+	@echo ++++++++++++++++++++++
+	@echo + Installing sources +
+	@echo ++++++++++++++++++++++
+	@echo
+	if [ $(SRCROOT) != . ]; then \
+	  $(PAX) -rw . $(SRCROOT); \
+	fi
+	find -d "$(SRCROOT)" \( -type d -a -name .svn -o \
+	                        -type f -a -name .DS_Store -o \
+				-name \*~ -o -name .\#\* \) \
+	  -exec rm -rf {} \;
+	rm -rf "$(SRCROOT)/test"
+
+#######################################################################
+
+clean:
+	@echo
+	@echo ++++++++++++
+	@echo + Cleaning +
+	@echo ++++++++++++
+	@echo
+	@if [ -d $(OBJROOT) -a "$(OBJROOT)" != / ]; then \
+	  echo '*** DELETING ' $(OBJROOT); \
+	  rm -rf $(OBJROOT); \
+	fi
+	@if [ -d $(SYMROOT) -a "$(SYMROOT)" != / ]; then \
+	  echo '*** DELETING ' $(SYMROOT); \
+	  rm -rf $(SYMROOT); \
+	fi
+	@if [ -d $(DSTROOT) -a "$(DSTROOT)" != / ]; then \
+	  echo '*** DELETING ' $(DSTROOT); \
+	  rm -rf $(DSTROOT); \
+	fi
+
+#######################################################################
+
+$(OBJROOT) $(SYMROOT) $(DSTROOT):
+	mkdir -p $@
+
+.PHONY: install installsrc clean EmbeddedHosted EmbeddedSim
diff --git a/src/LLVM/utils/buildit/build_llvm b/src/LLVM/utils/buildit/build_llvm
new file mode 100644
index 0000000..39ec1cc
--- /dev/null
+++ b/src/LLVM/utils/buildit/build_llvm
@@ -0,0 +1,373 @@
+#!/bin/sh
+# LLVM LOCAL file B&I
+
+set -x
+
+# Build LLVM the "Apple way".
+# Parameters:
+
+# The first parameter is a space-separated list of the architectures the
+# compilers will run on. For instance, "ppc i386". If the current machine
+# isn't in the list, it will (effectively) be added.
+HOSTS="$1"
+
+# The second parameter is a space-separated list of the architectures the
+# compilers will generate code for. If the current machine isn't in the list, a
+# compiler for it will get built anyway, but won't be installed.
+# FIXME: The list of targets is currently hard-coded and TARGETS is not used.
+TARGETS="$2"
+
+# The third parameter is the path to the compiler sources. There should be a
+# shell script named 'configure' in this directory. This script makes a copy...
+ORIG_SRC_DIR="$3"
+
+# The fourth parameter is the location where the LLVM will be installed. You can
+# move it once it's built, so this mostly controls the layout of $DEST_DIR.
+DEST_ROOT="$4"
+
+# The fifth parameter is the place where the compiler will be copied once it's
+# built.
+DEST_DIR="$5"
+
+# The sixth parameter is a directory in which to place information (like
+# unstripped executables and generated source files) helpful in debugging the
+# resulting compiler.
+SYM_DIR="$6"
+
+# The seventh parameter is a yes/no that indicates whether assertions should be
+# enabled in the LLVM libs/tools.
+LLVM_ASSERTIONS="$7"
+
+# The eighth parameter is a yes/no that indicates whether this is an optimized
+# build.
+LLVM_OPTIMIZED="$8"
+
+# The ninth parameter is a yes/no that indicates whether libLTO.dylib
+# should be installed.
+INSTALL_LIBLTO="$9"
+
+# A yes/no parameter that controls whether to cross-build for an ARM host.
+ARM_HOSTED_BUILD="${10}"
+
+# A yes/no parameter that controls whether to cross-build for the iOS simulator
+IOS_SIM_BUILD="${11}"
+
+# The version number of the submission, e.g. 1007.
+LLVM_SUBMIT_VERSION="${12}"
+
+# The subversion number of the submission, e.g. 03.
+LLVM_SUBMIT_SUBVERSION="${13}"
+
+# The current working directory is where the build will happen. It may already
+# contain a partial result of an interrupted build, in which case this script
+# will continue where it left off.
+DIR=`pwd`
+
+DARWIN_VERS=`uname -r | sed 's/\..*//'`
+echo DARWIN_VERS = $DARWIN_VERS
+
+################################################################################
+# Run the build.
+
+# Create the source tree we'll actually use to build, deleting
+# tcl since it doesn't actually build properly in a cross environment
+# and we don't really need it.
+SRC_DIR=$DIR/src
+rm -rf $SRC_DIR || exit 1
+mkdir $SRC_DIR || exit 1
+ln -s $ORIG_SRC_DIR/* $SRC_DIR/ || exit 1
+# We can't use the top-level Makefile as-is.  Remove the soft link:
+rm $SRC_DIR/Makefile || exit 1
+# Now create our own by editing the top-level Makefile, deleting every line marked "Apple-style":
+sed -e '/[Aa]pple-style/d' -e '/include.*GNUmakefile/d' $ORIG_SRC_DIR/Makefile > $SRC_DIR/Makefile || exit 1
+
+# Build the LLVM tree universal.
+mkdir -p $DIR/obj-llvm || exit 1
+cd $DIR/obj-llvm || exit 1
+
+if [ "$ARM_HOSTED_BUILD" = yes ]; then
+  # The cross-tools' build process expects to find an existing cross toolchain
+  # under names like 'arm-apple-darwin$DARWIN_VERS-as'; so make them.
+  rm -rf $DIR/bin || exit 1
+  mkdir $DIR/bin || exit 1
+  for prog in ar nm ranlib strip lipo ld as ; do
+    P=$DIR/bin/arm-apple-darwin$DARWIN_VERS-${prog}
+    T=`xcrun -sdk $SDKROOT -find ${prog}`
+    echo '#!/bin/sh' > $P || exit 1
+    echo 'exec '$T' "$@"' >> $P || exit 1
+    chmod a+x $P || exit 1
+  done
+  # Try to use the platform llvm-gcc. Fall back to gcc if it's not available.
+  for prog in gcc g++ ; do
+    P=$DIR/bin/arm-apple-darwin$DARWIN_VERS-${prog}
+    T=`xcrun -sdk $SDKROOT -find llvm-${prog}`
+    if [ "x$T" = "x" ] ; then
+      T=`xcrun -sdk $SDKROOT -find ${prog}`
+    fi
+    echo '#!/bin/sh' > $P || exit 1
+    echo 'exec '$T' -arch armv6 -isysroot '${SDKROOT}' "$@"' >> $P || exit 1
+    chmod a+x $P || exit 1
+  done
+
+  PATH=$DIR/bin:$PATH
+# otherwise, try to use llvm-gcc if it's available
+elif [ $DARWIN_VERS -gt 9 ]; then
+  # If the user has set CC or CXX, respect their wishes.  If not,
+  # compile with LLVM-GCC/LLVM-G++ if available; if LLVM is not
+  # available, fall back to usual GCC/G++ default.
+  savedPATH=$PATH ; PATH="/Developer/usr/bin:$PATH"
+  XTMPCC=$(which llvm-gcc)
+  if [ x$CC  = x -a x$XTMPCC != x ] ; then export CC=$XTMPCC  ; fi
+  XTMPCC=$(which llvm-g++)
+  if [ x$CXX = x -a x$XTMPCC != x ] ; then export CXX=$XTMPCC ; fi
+  PATH=$savedPATH
+  unset XTMPCC savedPATH
+fi
+
+if [ "$ARM_HOSTED_BUILD" = yes ]; then
+  configure_opts="--enable-targets=arm --host=arm-apple-darwin10 \
+                  --target=arm-apple-darwin10 --build=i686-apple-darwin10"
+elif [ "$IOS_SIM_BUILD" = yes ]; then
+  # Use a non-standard "darwin_sim" host triple to trigger a cross-build.
+  configure_opts="--enable-targets=x86 --host=i686-apple-darwin_sim \
+                  --build=i686-apple-darwin10"
+else
+  configure_opts="--enable-targets=arm,x86,powerpc,cbe"
+fi
+
+if [ \! -f Makefile.config ]; then
+  $SRC_DIR/configure --prefix=$DEST_DIR$DEST_ROOT $configure_opts \
+    --enable-assertions=$LLVM_ASSERTIONS \
+    --enable-optimized=$LLVM_OPTIMIZED \
+    --disable-bindings \
+    || exit 1
+fi
+
+SUBVERSION=`echo $RC_ProjectSourceVersion | sed -e 's/[^.]*\.\([0-9]*\).*/\1/'`
+
+if [ "x$SUBVERSION" != "x$RC_ProjectSourceVersion" ]; then
+    LLVM_SUBMIT_SUBVERSION=`printf "%02d" $SUBVERSION`
+    RC_ProjectSourceVersion=`echo $RC_ProjectSourceVersion | sed -e 's/\..*//'`
+    LLVM_SUBMIT_VERSION=$RC_ProjectSourceVersion
+fi
+
+if [ "x$LLVM_SUBMIT_SUBVERSION" = "x00" -o "x$LLVM_SUBMIT_SUBVERSION" = "x0" ]; then
+    LLVM_VERSION="$LLVM_SUBMIT_VERSION"
+else
+    LLVM_VERSION="$LLVM_SUBMIT_VERSION-$LLVM_SUBMIT_SUBVERSION"
+fi
+
+GCC_VER=`cc --version 2>/dev/null | sed 1q`
+
+if echo "$GCC_VER" | grep GCC > /dev/null; then
+    GCC_VER=`echo $GCC_VER | sed -e 's/.*(GCC) \([0-9.][0-9.]*\).*/\1/'`
+    MAJ_VER=`echo $GCC_VER | sed 's/\..*//'`
+    MIN_VER=`echo $GCC_VER | sed 's/[^.]*\.\([0-9]*\).*/\1/'`
+fi
+
+JOBS_FLAG=""
+
+# Note: If compiling with GCC 4.0, don't pass the -jN flag. Building universal
+# already has parallelism and we don't want to make the builders hit swap by
+# firing off too many gccs at the same time.
+if [ "x$MAJ_VER" != "x4" -o "x$MIN_VER" != "x0" ]; then
+    # Figure out how many make processes to run.
+    SYSCTL=`sysctl -n hw.activecpu`
+
+    # hw.activecpu only available in 10.2.6 and later
+    if [ -z "$SYSCTL" ]; then
+        SYSCTL=`sysctl -n hw.ncpu`
+    fi
+
+    # sysctl -n hw.* does not work when invoked via B&I chroot /BuildRoot.
+    # Builders can default to 2, since even if they are single processor,
+    # nothing else is running on the machine.
+    if [ -z "$SYSCTL" ]; then
+        SYSCTL=2
+    fi
+
+    JOBS_FLAG="-j $SYSCTL"
+fi
+
+make $JOBS_FLAG $OPTIMIZE_OPTS UNIVERSAL=1 UNIVERSAL_ARCH="$HOSTS" \
+    UNIVERSAL_SDK_PATH=$SDKROOT \
+    NO_RUNTIME_LIBS=1 \
+    DISABLE_EDIS=1 \
+    DEBUG_SYMBOLS=1 \
+    LLVM_SUBMIT_VERSION=$LLVM_SUBMIT_VERSION \
+    LLVM_SUBMIT_SUBVERSION=$LLVM_SUBMIT_SUBVERSION \
+    CXXFLAGS="-DLLVM_VERSION_INFO='\" Apple Build #$LLVM_VERSION\"'" \
+    VERBOSE=1
+
+if [ $? != 0 ] ; then
+    echo "error: LLVM 'make' failed!"
+    exit 1
+fi 
+
+################################################################################
+# Construct the actual destination root, by copying stuff from $DIR/dst-* to
+# $DEST_DIR, with occasional 'lipo' commands.
+
+cd $DEST_DIR || exit 1
+
+# Clean out DEST_DIR in case -noclean was passed to buildit.
+rm -rf * || exit 1
+
+cd $DIR/obj-llvm || exit 1
+
+# Install the tree into the destination directory.
+make $LOCAL_MAKEFLAGS $OPTIMIZE_OPTS UNIVERSAL=1 UNIVERSAL_ARCH="$HOSTS" \
+    NO_RUNTIME_LIBS=1 \
+    DISABLE_EDIS=1 \
+    DEBUG_SYMBOLS=1 \
+    LLVM_SUBMIT_VERSION=$LLVM_SUBMIT_VERSION \
+    LLVM_SUBMIT_SUBVERSION=$LLVM_SUBMIT_SUBVERSION \
+    OPTIMIZE_OPTION='-O3' VERBOSE=1 install
+
+if ! test $? == 0 ; then
+    echo "error: LLVM 'make install' failed!"
+    exit 1
+fi 
+
+# Install Version.h
+LLVM_MINOR_VERSION=`echo $LLVM_SUBMIT_SUBVERSION | sed -e 's,0*\([1-9][0-9]*\),\1,'`
+if [ "x$LLVM_MINOR_VERSION" = "x" ]; then
+    LLVM_MINOR_VERSION=0
+fi
+RC_ProjectSourceSubversion=`printf "%d" $LLVM_MINOR_VERSION`
+echo "#define LLVM_VERSION ${RC_ProjectSourceVersion}" > $DEST_DIR$DEST_ROOT/include/llvm/Version.h
+echo "#define LLVM_MINOR_VERSION ${RC_ProjectSourceSubversion}" >> $DEST_DIR$DEST_ROOT/include/llvm/Version.h
+
+if [ "x$LLVM_DEBUG" != "x1" ]; then
+    # Strip local symbols from llvm libraries.
+    #
+    # Use '-l' to strip i386 modules. N.B. that flag doesn't work with kext or
+    # PPC objects!
+    strip -Sl $DEST_DIR$DEST_ROOT/lib/*.[oa]
+    for f in `ls $DEST_DIR$DEST_ROOT/lib/*.so`; do
+        strip -Sxl $f
+    done
+fi
+
+# Copy over the tblgen utility.
+cp `find $DIR -name tblgen` $DEST_DIR$DEST_ROOT/bin
+
+# Remove .dir files 
+cd $DEST_DIR$DEST_ROOT
+rm -f bin/.dir etc/llvm/.dir lib/.dir
+
+# Remove PPC64 fat slices.
+cd $DEST_DIR$DEST_ROOT/bin
+if [ $MACOSX_DEPLOYMENT_TARGET = "10.4" ]; then
+    find . -perm 755 -type f \! \( -name '*gccas' -o -name '*gccld' -o -name llvm-config \) \
+        -exec lipo -extract ppc -extract i386 {} -output {} \;
+elif [ $MACOSX_DEPLOYMENT_TARGET = "10.5" ]; then
+    find . -perm 755 -type f \! \( -name '*gccas' -o -name '*gccld' -o -name llvm-config \) \
+        -exec lipo -extract ppc7400 -extract i386 {} -output {} \;
+else
+    find . -perm 755 -type f \! \( -name '*gccas' -o -name '*gccld' -o -name llvm-config \) \
+        -exec lipo -extract ppc7400 -extract i386 -extract x86_64 {} -output {} \;
+fi
+
+# The Hello dylib is an example of how to build a pass. No need to install it.
+rm $DEST_DIR$DEST_ROOT/lib/LLVMHello.dylib
+
+# Compress manpages
+MDIR=$DEST_DIR$DEST_ROOT/share/man/man1
+gzip -f $MDIR/*
+
+################################################################################
+# Create SYM_DIR with information required for debugging.
+
+# Figure out how many make processes to run.
+SYSCTL=`sysctl -n hw.activecpu`
+
+# hw.activecpu only available in 10.2.6 and later
+if [ -z "$SYSCTL" ]; then
+  SYSCTL=`sysctl -n hw.ncpu`
+fi
+
+# sysctl -n hw.* does not work when invoked via B&I chroot /BuildRoot. Builders
+# can default to 2, since even if they are single processor, nothing else is
+# running on the machine.
+if [ -z "$SYSCTL" ]; then
+  SYSCTL=2
+fi
+
+cd $SYM_DIR || exit 1
+
+# Clean out SYM_DIR in case -noclean was passed to buildit.
+rm -rf * || exit 1
+
+# Generate .dSYM files
+find $DEST_DIR -perm -0111 -type f \
+    ! \( -name '*.la' -o -name gccas -o -name gccld -o -name llvm-config -o -name '*.a' \) \
+    -print | xargs -n 1 -P ${SYSCTL} dsymutil
+
+# Save .dSYM files and .a archives
+cd $DEST_DIR || exit 1
+find . \( -path \*.dSYM/\* -or -name \*.a \) -print \
+    | cpio -pdml $SYM_DIR || exit 1
+
+# Save source files.
+mkdir $SYM_DIR/src || exit 1
+cd $DIR || exit 1
+find obj-* -name \*.\[chy\] -o -name \*.cpp -print \
+    | cpio -pdml $SYM_DIR/src || exit 1
+
+################################################################################
+# Install and strip libLTO.dylib
+
+cd $DEST_DIR$DEST_ROOT
+if [ "$INSTALL_LIBLTO" = "yes" ]; then
+  DT_HOME="$DEST_DIR/Developer/usr"
+  mkdir -p $DT_HOME/lib
+  mv lib/libLTO.dylib $DT_HOME/lib/libLTO.dylib
+
+  # Save a copy of the unstripped dylib
+  mkdir -p $SYM_DIR/Developer/usr/lib
+  cp $DT_HOME/lib/libLTO.dylib $SYM_DIR/Developer/usr/lib/libLTO.dylib
+
+  # Use '-l' to strip i386 modules. N.B. that flag doesn't work with kext or
+  # PPC objects!
+  strip -arch all -Sl $DT_HOME/lib/libLTO.dylib
+
+  if [ "x$DISABLE_USR_LINKS" == "x" ]; then
+    # Add a symlink in /usr/lib for B&I.
+    mkdir -p $DEST_DIR/usr/lib/
+    (cd $DEST_DIR/usr/lib && \
+      ln -s ../../Developer/usr/lib/libLTO.dylib ./libLTO.dylib)
+  fi
+else
+  rm -f lib/libLTO.dylib
+fi
+rm -f lib/libLTO.a lib/libLTO.la
+
+################################################################################
+# Remove debugging information from DEST_DIR.
+
+cd $DIR || exit 1
+
+find $DEST_DIR -name \*.a -print | xargs ranlib || exit 1
+find $DEST_DIR -name \*.dSYM -print | xargs rm -r || exit 1
+
+# Strip debugging information from files
+#
+# Use '-l' to strip i386 modules. N.B. that flag doesn't work with kext or
+# PPC objects!
+find $DEST_DIR -perm -0111 -type f \
+    ! \( -name '*.la' -o -name gccas -o -name gccld -o -name llvm-config \) \
+    -print | xargs -n 1 -P ${SYSCTL} strip -arch all -Sl
+
+chgrp -h -R wheel $DEST_DIR
+chgrp -R wheel $DEST_DIR
+
+################################################################################
+# Remove the docs directory
+
+rm -rf $DEST_DIR$DEST_ROOT/docs
+
+################################################################################
+# w00t! Done!
+
+exit 0
diff --git a/src/LLVM/utils/cgiplotNLT.pl b/src/LLVM/utils/cgiplotNLT.pl
new file mode 100644
index 0000000..0360e41
--- /dev/null
+++ b/src/LLVM/utils/cgiplotNLT.pl
@@ -0,0 +1,68 @@
+#!/usr/bin/perl
+#takes a test and a program from a dp and produces a gnuplot script
+#use like perl plotNLT.pl password Programs/MultiSource/Benchmarks/ASCI_Purple/SMG2000/smg2000 llc
+
+use CGI;
+use DBI;
+my $q = new CGI;
+
+# database information
+$db="llvmalpha";
+$host="localhost";
+$userid="llvmdbuser";
+$passwd=$q->param('pwd');
+$connectionInfo="dbi:mysql:$db;$host";
+
+# make connection to database
+$dbh = DBI->connect($connectionInfo,$userid,$passwd) or die DBI->errstr;
+
+
+$count = 0;
+while ($q->param('n' . $count))
+  {
+    $count++;
+  }
+
+$| = 1;
+print "Content-type: image/png", "\n\n";
+
+open CMDSTREAM, "|gnuplot";
+#open CMDSTREAM, "|echo";
+
+print CMDSTREAM "set terminal png\n";
+print CMDSTREAM "set output\n";
+print CMDSTREAM "set xdata time\n";
+print CMDSTREAM 'set timefmt "%Y-%m-%d"';
+print CMDSTREAM "\nplot";
+for ($iter = 0; $iter < $count; $iter++) {
+  if ($iter)
+    { print CMDSTREAM ","; }
+  print CMDSTREAM " '-' using 1:2 title \"" . $q->param('t' . $iter) . "," . $q->param('n' . $iter) . "\"with lines";
+}
+
+print CMDSTREAM "\n";
+
+for ($iter = 0; $iter < $count; $iter++) {
+
+  $prog = $q->param('n' . $iter);
+  $test = $q->param('t' . $iter);
+
+  $query = "Select RUN, VALUE from Tests where TEST = '$test' AND NAME = '$prog' ORDER BY RUN";
+  #print "\n$query\n";
+  
+  my $sth = $dbh->prepare( $query) || die "Can't prepare statement: $DBI::errstr";;
+  
+  my $rc = $sth->execute or die DBI->errstr;
+  
+  while(($da,$v) = $sth->fetchrow_array)
+    {
+      print CMDSTREAM "$da $v\n";
+    }
+  
+  print CMDSTREAM "e\n";
+}
+print CMDSTREAM "exit\n";
+close CMDSTREAM;
+
+# disconnect from database
+$dbh->disconnect;
diff --git a/src/LLVM/utils/check-each-file b/src/LLVM/utils/check-each-file
new file mode 100644
index 0000000..d53b4f3
--- /dev/null
+++ b/src/LLVM/utils/check-each-file
@@ -0,0 +1,150 @@
+#!/bin/sh

+# check-each-file

+# Used to narrow down a miscompilation to one .o file from a list. Please read

+# the usage procedure, below, for command-line syntax (or run it with --help).

+# This script depends on the llvm-native-gcc script.

+

+if [ x$1 = x--make-linker-script ]

+then

+	program=$2

+	linker=./link-$program

+	echo "Building $program with llvm-native-gcc"

+	rm -f $program

+	gmake -e $program CC=llvm-native-gcc CXX=llvm-native-gxx

+	echo "Erasing $program and re-linking it" 

+	rm -f $program

+	echo "rm -f $program" > $linker

+	gmake -n $program >> $linker

+	chmod 755 $linker

+	echo "Linker script created in $linker; testing it out"

+	output=`./$linker 2>&1`

+	case "$output" in

+		*undefined*reference*__main*) 

+			echo "$program appears to need a dummy __main function; adding one"

+			echo "void __main () { }" > __main.c

+			gcc -c __main.c

+			echo "Done; rebuilding $linker"

+			echo "rm -f $program" > $linker

+			gmake -n $program 2>&1 | sed '/gcc/s/$/__main.o/' >> $linker

+			./$linker > /dev/null 2>&1

+			if [ ! -x $program ]

+			then

+				echo "WARNING: linker script didn't work"

+			fi

+			;;

+		*)

+			if [ ! -x $program ]

+			then

+				echo "WARNING: linker script didn't work"

+			fi

+			;;

+	esac

+	echo "Linker script created in $linker; please check it manually"

+	exit 0

+fi

+

+checkfiles="$1"

+program="$2"

+linker="$3"

+checker="$4"

+

+usage () {

+	myname=`basename $0`

+	echo "$myname --make-linker-script PROGRAM"

+	echo "$myname OBJECTS-FILE PROGRAM LINKER CHECKER"

+	echo ""

+	echo "OBJECTS-FILE is a text file containing the names of all the .o files"

+	echo "PROGRAM is the name of the executable under test"

+	echo "(there must also exist a Makefile in the current directory which"

+	echo "has PROGRAM as a target)"

+	echo "LINKER is the script that builds PROGRAM; try --make-linker-script" 

+	echo "to automatically generate it"

+	echo "CHECKER is the script that exits 0 if PROGRAM is ok, 1 if it is not OK"

+	echo "(LINKER and CHECKER must be in your PATH, or you should specify ./)"

+	echo ""

+	echo "Bugs to <gaeke@uiuc.edu>."

+	exit 1

+}

+

+if [ x$1 = x--help ]

+then

+	usage

+fi

+

+if [ -z "$checkfiles" ]

+then

+	echo "ERROR: Must specify name of file w/ list of objects as 1st arg."

+	echo "(got \"$checkfiles\")"

+	usage

+fi

+if [ ! -f "$checkfiles" ]

+then

+	echo "ERROR: $checkfiles not found"

+	usage

+fi

+if [ -z "$program" ]

+then

+	echo "ERROR: Must specify name of program as 2nd arg."

+	usage

+fi

+if [ -z "$linker" ]

+then

+	echo "ERROR: Must specify name of link script as 3rd arg."

+	usage

+fi

+if [ ! -x "$linker" ]

+then

+	echo "ERROR: $linker not found or not executable"

+	echo "You may wish to try: $0 --make-linker-script $program"

+	usage

+fi

+if [ -z "$checker" ]

+then

+	echo "ERROR: Must specify name of $program check script as 3rd arg."

+	usage

+fi

+if [ ! -x "$checker" ]

+then

+	echo "ERROR: $checker not found or not executable"

+	usage

+fi

+

+files=`cat $checkfiles`

+echo "Recompiling everything with llvm-native-gcc"

+for f in $files

+do

+	rm -f $f

+	gmake $f CC=llvm-native-gcc CXX=llvm-native-gxx

+done

+rm -f $program

+$linker

+if $checker

+then

+	echo "Sorry, I can't help you, $program is OK when compiled with llvm-native-gcc"

+	exit 1

+fi

+for f in $files

+do

+	echo Trying to compile $f with native gcc and rebuild $program

+	mv ${f} ${f}__OLD__

+	gmake ${f} CC=gcc > /dev/null 2>&1

+	$linker

+	echo Checking validity of new $program

+	if $checker

+	then

+		echo Program is OK

+		okfiles="$okfiles $f"

+	else

+		echo Program is not OK

+		notokfiles="$notokfiles $f"

+	fi

+	mv ${f}__OLD__ ${f}

+done

+echo ""

+echo "Program is OK when these files are recompiled with native gcc: "

+echo "$okfiles"

+echo ""

+echo "Program is not OK when these files are recompiled with native gcc: "

+echo "$notokfiles"

+echo ""

+exit 0

diff --git a/src/LLVM/utils/codegen-diff b/src/LLVM/utils/codegen-diff
new file mode 100644
index 0000000..fd7f58d
--- /dev/null
+++ b/src/LLVM/utils/codegen-diff
@@ -0,0 +1,135 @@
+#!/usr/bin/perl

+

+use Getopt::Std;

+$DEBUG = 0;

+

+sub parse_objdump_file {

+  my ($filename) = @_;

+  my @result;

+  open (INPUT, $filename) or die "$filename: $!\n";

+  print "opened objdump output file $filename\n" if $DEBUG;

+  while (<INPUT>) {

+    if (/\s*([0-9a-f]*):\t(([0-9a-f]{2} )+) *\t(.*)$/) {

+      my ($addr, $bytes, $instr) = ($1, $2, $4);

+      $addr = "0x" . $addr;

+      $bytes =~ s/\s*(.*\S)\s*/$1/; # trim any remaining whitespace

+      $instr =~ s/\s*(.*\S)\s*/$1/;

+      push (@result, {'addr' => $addr, 'bytes' => $bytes, 'instr' => $instr});

+      print "addr=$addr bytes='$bytes' instr='$instr'\n" if $DEBUG;

+    }

+  }

+  close INPUT;

+  return @result;

+}

+

+sub parse_gdb_file {

+  my ($filename) = @_;

+  my @result;

+  my $got_addr;

+  open (INPUT, $filename) or die "$filename: $!\n";

+  print "opened gdb output file $filename\n" if $DEBUG;

+  while (<INPUT>) {

+    if (/^(0x[0-9a-f]*):\t([^\t]*)\t[^:]*:\t((0x[0-9a-f]{2}\s*)+)\s*$/) {

+      my ($addr, $bytes, $instr) = ($1, $3, $2);

+      $bytes =~ s/0x//g;

+      $bytes =~ s/\s+/ /g;           # regularize whitespace

+      $bytes =~ s/\s*(.*\S)\s*/$1/;  # trim any remaining whitespace

+      $instr =~ s/\s*(.*\S)\s*/$1/;

+      push (@result, {'addr' => $addr, 'bytes' => $bytes, 'instr' => $instr});

+      print "addr=$addr bytes='$bytes' instr='$instr'\n" if $DEBUG;

+    } elsif (/^(0x[0-9a-f]*):\t$/) { # deal with gdb's line breaker

+      $got_addr = $1;

+    } elsif ($got_addr && /^    ([^\t]*)\t[^:]*:\t((0x[0-9a-f]{2}\s*)+)\s*$/) {

+      my ($addr, $bytes, $instr) = ($got_addr, $2, $1);

+      $bytes =~ s/0x//g;

+      $bytes =~ s/\s+/ /g;           # regularize whitespace

+      $bytes =~ s/\s*(.*\S)\s*/$1/;  # trim any remaining whitespace

+      $instr =~ s/\s*(.*\S)\s*/$1/;

+      push (@result, {'addr' => $addr, 'bytes' => $bytes, 'instr' => $instr});

+      print "addr=$addr bytes='$bytes' instr='$instr'\n" if $DEBUG;

+      undef $got_addr;

+    }

+  }

+  close INPUT;

+  return @result;

+}

+

+sub binary_diffs {

+  my ($objdump_file, $gdb_file) = @_;

+  my @file1 = parse_objdump_file ($objdump_file);

+  my @file2 = parse_gdb_file ($gdb_file);

+  my $lastrecord = ($#file1 >= $#file2) ? ($#file1) : ($#file2);

+  for (my $i = 0; $i <= $lastrecord; ++$i) {

+    my $d1 = $file1[$i];

+    my $d2 = $file2[$i];

+    if ($d1->{'bytes'} ne $d2->{'bytes'}) {

+      next if (($d1->{'instr'} eq $d2->{'instr'}) && $opt_d);

+      printf "0x%08x:\t%30s \t%s\n", 0+$d1->{'addr'}, $d1->{'bytes'}, $d1->{'instr'};

+      printf "0x%08x:\t%30s \t%s\n\n", 0+$d2->{'addr'}, $d2->{'bytes'}, $d2->{'instr'};

+    }

+  }

+}

+

+&getopts('d');

+$objdump_file = $ARGV[0];

+$gdb_file = $ARGV[1];

+binary_diffs ($objdump_file, $gdb_file);

+exit (0);

+__END__

+=pod

+

+=head1 NAME

+

+codegen-diff

+

+=head1 SYNOPSIS

+

+codegen-diff [-d] I<OBJDUMP-OUTPUT-FILE> I<GDB-DISASSEMBLY-FILE>

+

+=head1 DESCRIPTION

+

+B<codegen-diff> is a program that tries to show you the differences

+between the code that B<llc> generated and the code that B<lli> generated.

+

+The way you use it is as follows: first, you create I<OBJDUMP-OUTPUT-FILE>

+by running B<objdump> on the B<llc> compiled and linked binary. You need to

+trim down the result so it contains only the function of interest.

+

+Second, you create I<GDB-DISASSEMBLY-FILE> by running B<gdb>, with my patch

+to print out hex bytes in the B<disassemble> command output, on

+B<lli>.  Set a breakpoint in C<Emitter::finishFunction()> and wait until

+the function you want is compiled.  Then use the B<disassemble> command

+to print out the assembly dump of the function B<lli> just compiled.

+(Use C<lli -debug> to find out where the function starts and ends in memory.)

+It's easiest to save this output by using B<script>.

+

+Finally, you run B<codegen-diff>, as indicated in the Synopsis section of

+this manpage. It will print out a two-line stanza for each mismatched

+instruction, with the  B<llc> version first, and the  B<lli> version second.

+

+=head1 OPTIONS

+

+=over 4

+

+=item -d

+

+Don't show instructions where the bytes are different but they

+disassemble to the same thing. This puts a lot of trust in the

+disassembler, but it might help you highlight the more egregious cases

+of misassembly.

+

+=back

+

+=head1 AUTHOR

+

+B<codegen-diff> was written by Brian Gaeke.

+

+=head1 SEE ALSO

+

+L<gdb(1)>, L<objdump(1)>, L<script(1)>.

+

+You will need my B<gdb> patch:

+

+  http://llvm.cs.uiuc.edu/~gaeke/gdb-disassembly-print-bytes.patch

+

+=cut

diff --git a/src/LLVM/utils/count/CMakeLists.txt b/src/LLVM/utils/count/CMakeLists.txt
new file mode 100644
index 0000000..e124f61
--- /dev/null
+++ b/src/LLVM/utils/count/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_executable(count
+  count.c
+  )
diff --git a/src/LLVM/utils/count/Makefile b/src/LLVM/utils/count/Makefile
new file mode 100644
index 0000000..8de076a
--- /dev/null
+++ b/src/LLVM/utils/count/Makefile
@@ -0,0 +1,20 @@
+##===- utils/count/Makefile --------------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+TOOLNAME = count
+USEDLIBS = 
+
+# This tool has no plugins, optimize startup time.
+TOOL_NO_EXPORTS = 1
+
+# Don't install this utility
+NO_INSTALL = 1
+
+include $(LEVEL)/Makefile.common
diff --git a/src/LLVM/utils/count/count.c b/src/LLVM/utils/count/count.c
new file mode 100644
index 0000000..ae96791
--- /dev/null
+++ b/src/LLVM/utils/count/count.c
@@ -0,0 +1,50 @@
+/*===- count.c - The 'count' testing tool ---------------------------------===*\
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+\*===----------------------------------------------------------------------===*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+  unsigned Count, NumLines, NumRead;
+  char Buffer[4096], *End;
+
+  if (argc != 2) {
+    fprintf(stderr, "usage: %s <expected line count>\n", argv[0]);
+    return 2;
+  }
+
+  Count = strtol(argv[1], &End, 10);
+  if (*End != '\0' && End != argv[1]) {
+    fprintf(stderr, "%s: invalid count argument '%s'\n", argv[0], argv[1]);
+    return 2;
+  }
+
+  NumLines = 0;
+  do {
+    unsigned i;
+
+    NumRead = fread(Buffer, 1, sizeof(Buffer), stdin);
+
+    for (i = 0; i != NumRead; ++i)
+      if (Buffer[i] == '\n')
+        ++NumLines;
+  } while (NumRead == sizeof(Buffer));
+    
+  if (!feof(stdin)) {
+    fprintf(stderr, "%s: error reading stdin\n", argv[0]);
+    return 3;
+  }
+
+  if (Count != NumLines) {
+    fprintf(stderr, "Expected %d lines, got %d.\n", Count, NumLines);
+    return 1;
+  }
+
+  return 0;
+}
diff --git a/src/LLVM/utils/countloc.sh b/src/LLVM/utils/countloc.sh
new file mode 100644
index 0000000..4d1b775
--- /dev/null
+++ b/src/LLVM/utils/countloc.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+##===- utils/countloc.sh - Counts Lines Of Code --------------*- Script -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+#
+# This script finds all the source code files in the source code directories
+# (excluding certain things), runs "wc -l" on them to get the number of lines in
+# each file and then sums up and prints the total with awk. 
+#
+# The script takes one optional option, -topdir, which specifies the top llvm
+# source directory. If it is not specified then the llvm-config tool is 
+# consulted to find top source dir.  
+#
+# Note that the implementation is based on llvmdo. See that script for more
+# details.
+##===----------------------------------------------------------------------===##
+
+if test $# -gt 1 ; then
+  if test "$1" = "-topdir" ; then
+    TOPDIR="$2"
+    shift; shift;
+  else
+    TOPDIR=`llvm-config --src-root`
+  fi
+fi
+
+if test -d "$TOPDIR" ; then
+  cd $TOPDIR
+  ./utils/llvmdo -topdir "$TOPDIR" -dirs "include lib tools test utils examples" -code-only wc -l | awk '\
+      BEGIN { loc=0; } \
+      { loc += $1; } \
+      END { print loc; }'
+else
+  echo "Can't find LLVM top directory"
+fi
diff --git a/src/LLVM/utils/crosstool/ARM/README b/src/LLVM/utils/crosstool/ARM/README
new file mode 100644
index 0000000..ba58583
--- /dev/null
+++ b/src/LLVM/utils/crosstool/ARM/README
@@ -0,0 +1,37 @@
+HOWTO create an LLVM crosstool from x86_64/Linux to ARM/Linux
+=============================================================
+
+1. % llvm/utils/crosstool/create-snapshots.sh
+
+   This will create llvm-[REV_L].tar.bz2 and llvm-gcc-4.2-[REV_G].tar.bz2,
+   where:
+     REV_L is the revision at which "llvm" was checked out, and
+     REV_G is the revision at which "llvm-gcc-4.2" was checked out
+
+   Note that REV_L might REV_G might not be the same revision.
+
+2. Download CodeSourcery toolchain.  The exact location depends on your
+   $CROSS_TARGET but the script will tell you what the location of the file is
+   if you run it without having the file available.
+
+   For example, if you're using $CROSS_TARGET == "arm-none-linux-gnueabi" then
+   you need to download:
+
+   http://www.codesourcery.com/sgpp/lite/arm/portal/package1787/public/arm-none-linux-gnueabi/arm-2007q3-51-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
+
+   NOTE: simply changing $CROSS_TARGET and modifying the URL accordingly will
+   not work -- you'll need to go to http://www.codesourcery.com and find the
+   correct file, as the release number in the file will also be different (e.g.,
+   in the file above, the release number is "51").
+
+3. You can override most values in the script without modifying it, e.g.
+   $INSTALL_ROOT (if you want to install in directory other than /usr/local).
+
+   Run the script as:
+
+   % env INSTALL_ROOT=[dir to install in] \
+         CODE_SOURCERY_PKG_PATH=[dir where you downloaded CodeSourcery tarball] \
+         LLVM_PKG_PATH=[dir where you stored your LLVM and LLVM-GCC snapshots] \
+         LLVM_SVN_REV=${REV_L} \
+         LLVMGCC_SVN_REV=${REV_G} \
+         build-install-linux.sh
diff --git a/src/LLVM/utils/crosstool/ARM/build-install-linux.sh b/src/LLVM/utils/crosstool/ARM/build-install-linux.sh
new file mode 100644
index 0000000..f3f8df9
--- /dev/null
+++ b/src/LLVM/utils/crosstool/ARM/build-install-linux.sh
@@ -0,0 +1,200 @@
+#!/bin/bash
+#
+# Compiles and installs a Linux/x86_64 -> Linux/ARM crosstool based on LLVM and
+# LLVM-GCC-4.2 using SVN snapshots in provided tarballs.
+
+set -o nounset
+set -o errexit
+
+echo -n "Welcome to LLVM Linux/X86_64 -> Linux/ARM crosstool "
+echo "builder/installer; some steps will require sudo privileges."
+
+readonly INSTALL_ROOT="${INSTALL_ROOT:-/usr/local/crosstool}"
+# Both $USER and root *must* have read/write access to this dir.
+readonly SCRATCH_ROOT=$(mktemp -d "${TMPDIR:-/tmp}/llvm-project.XXXXXX")
+readonly SRC_ROOT="${SCRATCH_ROOT}/src"
+readonly OBJ_ROOT="${SCRATCH_ROOT}/obj"
+
+readonly CROSS_HOST="x86_64-unknown-linux-gnu"
+readonly CROSS_TARGET="arm-none-linux-gnueabi"
+readonly CROSS_MARCH="${CROSS_MARCH:-armv6}"
+
+readonly CODE_SOURCERY="${INSTALL_ROOT}/codesourcery"
+readonly CODE_SOURCERY_PKG_PATH="${CODE_SOURCERY_PKG_PATH:-${HOME}/codesourcery}"
+readonly CODE_SOURCERY_HTTP="http://www.codesourcery.com/sgpp/lite/arm/portal/package1787/public"
+readonly CODE_SOURCERY_PKG="arm-2007q3-51-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2"
+readonly CODE_SOURCERY_ROOT="${CODE_SOURCERY}/arm-2007q3"
+readonly CODE_SOURCERY_BIN="${CODE_SOURCERY_ROOT}/bin"
+# Make sure ${CROSS_TARGET}-* binutils are in command path
+export PATH="${CODE_SOURCERY_BIN}:${PATH}"
+
+readonly CROSS_TARGET_AS="${CODE_SOURCERY_BIN}/${CROSS_TARGET}-as"
+readonly CROSS_TARGET_LD="${CODE_SOURCERY_BIN}/${CROSS_TARGET}-ld"
+
+readonly SYSROOT="${CODE_SOURCERY_ROOT}/${CROSS_TARGET}/libc"
+
+readonly LLVM_PKG_PATH="${LLVM_PKG_PATH:-${HOME}/llvm-project/snapshots}"
+
+# Latest SVN revisions known to be working in this configuration.
+readonly LLVM_DEFAULT_REV="74530"
+readonly LLVMGCC_DEFAULT_REV="74535"
+
+readonly LLVM_PKG="llvm-${LLVM_SVN_REV:-${LLVM_DEFAULT_REV}}.tar.bz2"
+readonly LLVM_SRC_DIR="${SRC_ROOT}/llvm"
+readonly LLVM_OBJ_DIR="${OBJ_ROOT}/llvm"
+readonly LLVM_INSTALL_DIR="${INSTALL_ROOT}/${CROSS_TARGET}/llvm"
+
+readonly LLVMGCC_PKG="llvm-gcc-4.2-${LLVMGCC_SVN_REV:-${LLVMGCC_DEFAULT_REV}}.tar.bz2"
+readonly LLVMGCC_SRC_DIR="${SRC_ROOT}/llvm-gcc-4.2"
+readonly LLVMGCC_OBJ_DIR="${OBJ_ROOT}/llvm-gcc-4.2"
+readonly LLVMGCC_INSTALL_DIR="${INSTALL_ROOT}/${CROSS_TARGET}/llvm-gcc-4.2"
+
+readonly MAKE_OPTS="${MAKE_OPTS:--j2}"
+
+# Params:
+#   $1: directory to be created
+#   $2: optional mkdir command prefix, e.g. "sudo"
+createDir() {
+  if [[ ! -e $1 ]]; then
+    ${2:-} mkdir -p $1
+  elif [[ -e $1 && ! -d $1 ]]; then
+    echo "$1 exists but is not a directory; exiting."
+    exit 3
+  fi
+}
+
+sudoCreateDir() {
+  createDir $1 sudo
+  sudo chown ${USER} $1
+}
+
+# Prints out and runs the command, but without logging -- intended for use with
+# lightweight commands that don't have useful output to parse, e.g. mkdir, tar,
+# etc.
+runCommand() {
+  local message="$1"
+  shift
+  echo "=> $message"
+  echo "==> Running: $*"
+  $*
+}
+
+runAndLog() {
+  local message="$1"
+  local log_file="$2"
+  shift 2
+  echo "=> $message; log in $log_file"
+  echo "==> Running: $*"
+  # Pop-up a terminal with the output of the current command?
+  # e.g.: xterm -e /bin/bash -c "$* >| tee $log_file"
+  $* &> $log_file
+  if [[ $? != 0 ]]; then
+    echo "Error occurred: see most recent log file for details."
+    exit
+  fi
+}
+
+installCodeSourcery() {
+  # Unpack the tarball, creating the CodeSourcery dir, if necessary.
+  if [[ ! -d ${CODE_SOURCERY_ROOT} ]]; then
+    sudoCreateDir ${CODE_SOURCERY}
+    cd ${CODE_SOURCERY}
+    if [[ -e ${CODE_SOURCERY_PKG_PATH}/${CODE_SOURCERY_PKG} ]]; then
+      runCommand "Unpacking CodeSourcery in ${CODE_SOURCERY}" \
+          tar jxf ${CODE_SOURCERY_PKG_PATH}/${CODE_SOURCERY_PKG}
+    else
+      echo -n "CodeSourcery tarball not found in "
+      echo "${CODE_SOURCERY_PKG_PATH}/${CODE_SOURCERY_PKG}"
+      echo -n "Fix the path or download it from "
+      echo "${CODE_SOURCERY_HTTP}/${CROSS_TARGET}/${CODE_SOURCERY_PKG}"
+      exit
+    fi
+  else
+    echo "CodeSourcery install dir already exists; skipping."
+  fi
+
+  # Verify our CodeSourcery toolchain installation.
+  if [[ ! -d "${SYSROOT}" ]]; then
+    echo -n "Error: CodeSourcery does not contain libc for ${CROSS_TARGET}: "
+    echo "${SYSROOT} not found."
+    exit
+  fi
+
+  for tool in ${CROSS_TARGET_AS} ${CROSS_TARGET_LD}; do
+    if [[ ! -e $tool ]]; then
+      echo "${tool} not found; exiting."
+      exit
+    fi
+  done
+}
+
+installLLVM() {
+  if [[ -d ${LLVM_INSTALL_DIR} ]]; then
+    echo "LLVM install dir ${LLVM_INSTALL_DIR} exists; skipping."
+    return
+  fi
+
+  sudoCreateDir ${LLVM_INSTALL_DIR}
+
+  # Unpack LLVM tarball; should create the directory "llvm".
+  cd ${SRC_ROOT}
+  runCommand "Unpacking LLVM" tar jxf ${LLVM_PKG_PATH}/${LLVM_PKG}
+
+  # Configure, build, and install LLVM.
+  createDir ${LLVM_OBJ_DIR}
+  cd ${LLVM_OBJ_DIR}
+  runAndLog "Configuring LLVM" ${LLVM_OBJ_DIR}/llvm-configure.log \
+      ${LLVM_SRC_DIR}/configure \
+      --disable-jit \
+      --enable-optimized \
+      --prefix=${LLVM_INSTALL_DIR} \
+      --target=${CROSS_TARGET} \
+      --with-llvmgccdir=${LLVMGCC_INSTALL_DIR}
+  runAndLog "Building LLVM" ${LLVM_OBJ_DIR}/llvm-build.log \
+      make ${MAKE_OPTS}
+  runAndLog "Installing LLVM" ${LLVM_OBJ_DIR}/llvm-install.log \
+      make ${MAKE_OPTS} install
+}
+
+installLLVMGCC() {
+  if [[ -d ${LLVMGCC_INSTALL_DIR} ]]; then
+    echo "LLVM-GCC install dir ${LLVMGCC_INSTALL_DIR} exists; skipping."
+    return
+  fi
+
+  sudoCreateDir ${LLVMGCC_INSTALL_DIR}
+
+  # Unpack LLVM-GCC tarball; should create the directory "llvm-gcc-4.2".
+  cd ${SRC_ROOT}
+  runCommand "Unpacking LLVM-GCC" tar jxf ${LLVM_PKG_PATH}/${LLVMGCC_PKG}
+
+  # Configure, build, and install LLVM-GCC.
+  createDir ${LLVMGCC_OBJ_DIR}
+  cd ${LLVMGCC_OBJ_DIR}
+  runAndLog "Configuring LLVM-GCC" ${LLVMGCC_OBJ_DIR}/llvmgcc-configure.log \
+      ${LLVMGCC_SRC_DIR}/configure \
+      --enable-languages=c,c++ \
+      --enable-llvm=${LLVM_INSTALL_DIR} \
+      --prefix=${LLVMGCC_INSTALL_DIR} \
+      --program-prefix=llvm- \
+      --target=${CROSS_TARGET} \
+      --with-arch=${CROSS_MARCH} \
+      --with-as=${CROSS_TARGET_AS} \
+      --with-ld=${CROSS_TARGET_LD} \
+      --with-sysroot=${SYSROOT}
+  runAndLog "Building LLVM-GCC" ${LLVMGCC_OBJ_DIR}/llvmgcc-build.log \
+      make
+  runAndLog "Installing LLVM-GCC" ${LLVMGCC_OBJ_DIR}/llvmgcc-install.log \
+      make install
+}
+
+echo "Building in ${SCRATCH_ROOT}; installing in ${INSTALL_ROOT}"
+
+createDir ${SRC_ROOT}
+createDir ${OBJ_ROOT}
+
+installCodeSourcery
+installLLVM
+installLLVMGCC
+
+echo "Done."
diff --git a/src/LLVM/utils/crosstool/create-snapshots.sh b/src/LLVM/utils/crosstool/create-snapshots.sh
new file mode 100644
index 0000000..d70232a
--- /dev/null
+++ b/src/LLVM/utils/crosstool/create-snapshots.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+#
+# Creates LLVM SVN snapshots: llvm-$REV.tar.bz2 and llvm-gcc-4.2-$REV.tar.bz2,
+# where $REV is an SVN revision of LLVM.  This is used for creating stable
+# tarballs which can be used to build known-to-work crosstools.
+#
+# Syntax:
+#   $0 [REV] -- grabs the revision $REV from SVN; if not specified, grabs the
+#   latest SVN revision.
+
+set -o nounset
+set -o errexit
+
+readonly LLVM_PROJECT_SVN="http://llvm.org/svn/llvm-project"
+
+getLatestRevisionFromSVN() {
+  svn info ${LLVM_PROJECT_SVN} | egrep ^Revision | sed 's/^Revision: //'
+}
+
+readonly REV="${1:-$(getLatestRevisionFromSVN)}"
+
+createTarballFromSVN() {
+  local module=$1
+  local log="${module}.log"
+  echo "Running: svn export -r ${REV} ${module}; log in ${log}"
+  svn -q export -r ${REV} ${LLVM_PROJECT_SVN}/${module}/trunk \
+      ${module} > ${log} 2>&1
+
+  # Create "module-revision.tar.bz2" packages from the SVN checkout dirs.
+  local tarball="${module}-${REV}.tar.bz2"
+  echo "Creating tarball: ${tarball}"
+  tar cjf ${tarball} ${module}
+
+  echo "Cleaning up '${module}'"
+  rm -rf ${module} ${log}
+}
+
+for module in "llvm" "llvm-gcc-4.2"; do
+  createTarballFromSVN ${module}
+done
+
diff --git a/src/LLVM/utils/emacs/README b/src/LLVM/utils/emacs/README
new file mode 100644
index 0000000..08621c8
--- /dev/null
+++ b/src/LLVM/utils/emacs/README
@@ -0,0 +1,27 @@
+-*- llvm/utils/emacs/README -*-

+

+These are syntax highlighting files for the Emacs and XEmacs editors. Included

+are:

+

+* llvm-mode.el

+

+  Syntax highlighting mode for LLVM assembly files. To use, add this code to

+  your ~/.emacs :

+

+  (setq load-path

+    (cons (expand-file-name "path-to-llvm/utils/emacs") load-path))

+  (require 'llvm-mode)

+  

+* tablegen-mode.el

+

+  Syntax highlighting mode for TableGen description files. To use, add this code

+  to your ~/.emacs:

+

+  (setq load-path

+    (cons (expand-file-name "path-to-llvm/utils/emacs") load-path))

+  (require 'tablegen-mode)

+

+

+Note: If you notice missing or incorrect syntax highlighting, please contact

+<llvmbugs [at] cs.uiuc.edu>; if you wish to provide a patch to improve the

+functionality, it will be most appreciated. Thank you.

diff --git a/src/LLVM/utils/emacs/emacs.el b/src/LLVM/utils/emacs/emacs.el
new file mode 100644
index 0000000..bd7eaa8
--- /dev/null
+++ b/src/LLVM/utils/emacs/emacs.el
@@ -0,0 +1,39 @@
+;; LLVM coding style guidelines in emacs

+;; Maintainer: LLVM Team, http://llvm.org/

+;; Modified:   2009-07-28

+

+;; Max 80 cols per line, indent by two spaces, no tabs.

+;; Apparently, this does not affect tabs in Makefiles.

+(custom-set-variables

+  '(fill-column 80)

+  '(c++-indent-level 2)

+  '(c-basic-offset 2)

+  '(indent-tabs-mode nil))

+

+

+;; Alternative to setting the global style.  Only files with "llvm" in

+;; their names will automatically set to the llvm.org coding style.

+(c-add-style "llvm.org"

+             '((fill-column . 80)

+	       (c++-indent-level . 2)

+	       (c-basic-offset . 2)

+	       (indent-tabs-mode . nil)

+               (c-offsets-alist . ((innamespace 0)))))

+

+(add-hook 'c-mode-hook

+	  (function

+	   (lambda nil 

+	     (if (string-match "llvm" buffer-file-name)

+		 (progn

+		   (c-set-style "llvm.org")

+		   )

+	       ))))

+

+(add-hook 'c++-mode-hook

+	  (function

+	   (lambda nil 

+	     (if (string-match "llvm" buffer-file-name)

+		 (progn

+		   (c-set-style "llvm.org")

+		   )

+	       ))))

diff --git a/src/LLVM/utils/emacs/llvm-mode.el b/src/LLVM/utils/emacs/llvm-mode.el
new file mode 100644
index 0000000..56b60bb
--- /dev/null
+++ b/src/LLVM/utils/emacs/llvm-mode.el
@@ -0,0 +1,128 @@
+;; Maintainer:  The LLVM team, http://llvm.org/

+;; Description: Major mode for the LLVM assembler language.

+;; Updated:     2007-09-19

+

+;; Create mode-specific tables.

+(defvar llvm-mode-syntax-table nil

+  "Syntax table used while in LLVM mode.")

+

+(defvar llvm-font-lock-keywords

+  (list

+   ;; Comments

+   '(";.*" . font-lock-comment-face)

+   ;; Variables

+   '("%[-a-zA-Z$\._][-a-zA-Z$\._0-9]*" . font-lock-variable-name-face)

+   ;; Labels

+   '("[-a-zA-Z$\._0-9]+:" . font-lock-variable-name-face)

+   ;; Strings

+   '("\"[^\"]+\"" . font-lock-string-face)

+   ;; Unnamed variable slots

+   '("%[-]?[0-9]+" . font-lock-variable-name-face)

+   ;; Types

+   '("\\bvoid\\b\\|\\bi[0-9]+\\b\\|\\float\\b\\|\\bdouble\\b\\|\\btype\\b\\|\\blabel\\b\\|\\bopaque\\b" . font-lock-type-face)

+   ;; Integer literals

+   '("\\b[-]?[0-9]+\\b" . font-lock-preprocessor-face)

+   ;; Floating point constants

+   '("\\b[-+]?[0-9]+\.[0-9]*\([eE][-+]?[0-9]+\)?\\b" . font-lock-preprocessor-face)

+   ;; Hex constants

+   '("\\b0x[0-9A-Fa-f]+\\b" . font-lock-preprocessor-face)

+   ;; Keywords

+   '("\\bbegin\\b\\|\\bend\\b\\|\\btrue\\b\\|\\bfalse\\b\\|\\bzeroinitializer\\b\\|\\bdeclare\\b\\|\\bdefine\\b\\|\\bglobal\\b\\|\\bconstant\\b\\|\\bconst\\b\\|\\binternal\\b\\|\\blinkonce\\b\\|\\blinkonce_odr\\b\\|\\bweak\\b\\|\\bweak_odr\\b\\|\\bappending\\b\\|\\buninitialized\\b\\|\\bimplementation\\b\\|\\b\\.\\.\\.\\b\\|\\bnull\\b\\|\\bundef\\b\\|\\bto\\b\\|\\bexcept\\b\\|\\bnot\\b\\|\\btarget\\b\\|\\bendian\\b\\|\\blittle\\b\\|\\bbig\\b\\|\\bpointersize\\b\\|\\bdeplibs\\b\\|\\bvolatile\\b\\|\\bfastcc\\b\\|\\bcoldcc\\b\\|\\bcc\\b" . font-lock-keyword-face)

+   ;; Arithmetic and Logical Operators

+   '("\\badd\\b\\|\\bsub\\b\\|\\bmul\\b\\|\\bdiv\\b\\|\\brem\\b\\|\\band\\b\\|\\bor\\b\\|\\bxor\\b\\|\\bset\\(ne\\b\\|\\beq\\b\\|\\blt\\b\\|\\bgt\\b\\|\\ble\\b\\|\\bge\\b\\)" . font-lock-keyword-face)

+   ;; Special instructions

+   '("\\bphi\\b\\|\\btail\\b\\|\\bcall\\b\\|\\bcast\\b\\|\\bselect\\b\\|\\bto\\b\\|\\bshl\\b\\|\\bshr\\b\\|\\bvaarg\\b\\|\\bvanext\\b" . font-lock-keyword-face)

+   ;; Control instructions

+   '("\\bret\\b\\|\\bbr\\b\\|\\bswitch\\b\\|\\binvoke\\b\\|\\bunwind\\b\\|\\bunreachable\\b" . font-lock-keyword-face)

+   ;; Memory operators

+   '("\\bmalloc\\b\\|\\balloca\\b\\|\\bfree\\b\\|\\bload\\b\\|\\bstore\\b\\|\\bgetelementptr\\b" . font-lock-keyword-face)

+   )

+  "Syntax highlighting for LLVM"

+  )

+

+;; ---------------------- Syntax table ---------------------------

+;; Shamelessly ripped from jasmin.el

+;; URL: http://www.neilvandyke.org/jasmin-emacs/jasmin.el.html

+

+(if (not llvm-mode-syntax-table)

+    (progn

+      (setq llvm-mode-syntax-table (make-syntax-table))

+      (mapcar (function (lambda (n)

+                          (modify-syntax-entry (aref n 0)

+                                               (aref n 1)

+                                               llvm-mode-syntax-table)))

+              '(

+                ;; whitespace (` ')

+                [?\^m " "]

+                [?\f  " "]

+                [?\n  " "]

+                [?\t  " "]

+                [?\   " "]

+                ;; word constituents (`w')

+                ;;[?<  "w"]

+                ;;[?>  "w"]

+                [?\%  "w"]

+                ;;[?_  "w  "]

+                ;; comments

+                [?\;  "< "]

+                [?\n  "> "]

+                ;;[?\r  "> "]

+                ;;[?\^m "> "]

+                ;; symbol constituents (`_')

+                ;; punctuation (`.')

+                ;; open paren (`(')

+                [?\( "("]

+                [?\[ "("]

+                [?\{ "("]

+                ;; close paren (`)')

+                [?\) ")"]

+                [?\] ")"]

+                [?\} ")"]

+                ;; string quote ('"')

+                [?\" "\""]

+                ))))

+

+;; --------------------- Abbrev table -----------------------------

+

+(defvar llvm-mode-abbrev-table nil

+  "Abbrev table used while in LLVM mode.")

+(define-abbrev-table 'llvm-mode-abbrev-table ())

+

+(defvar llvm-mode-hook nil)

+(defvar llvm-mode-map nil)   ; Create a mode-specific keymap.

+

+(if (not llvm-mode-map)

+    ()  ; Do not change the keymap if it is already set up.

+  (setq llvm-mode-map (make-sparse-keymap))

+  (define-key llvm-mode-map "\t" 'tab-to-tab-stop)

+  (define-key llvm-mode-map "\es" 'center-line)

+  (define-key llvm-mode-map "\eS" 'center-paragraph))

+

+

+(defun llvm-mode ()

+  "Major mode for editing LLVM source files.

+  \\{llvm-mode-map}

+  Runs llvm-mode-hook on startup."

+  (interactive)

+  (kill-all-local-variables)

+  (use-local-map llvm-mode-map)         ; Provides the local keymap.

+  (setq major-mode 'llvm-mode)          

+

+  (make-local-variable 'font-lock-defaults)

+  (setq major-mode 'llvm-mode           ; This is how describe-mode

+                                        ;   finds the doc string to print.

+  mode-name "LLVM"                      ; This name goes into the modeline.

+  font-lock-defaults `(llvm-font-lock-keywords))

+

+  (setq local-abbrev-table llvm-mode-abbrev-table)

+  (set-syntax-table llvm-mode-syntax-table)

+  (setq comment-start ";")

+  (run-hooks 'llvm-mode-hook))          ; Finally, this permits the user to

+                                        ;   customize the mode with a hook.

+

+;; Associate .ll files with llvm-mode

+(setq auto-mode-alist

+   (append '(("\\.ll$" . llvm-mode)) auto-mode-alist))

+

+(provide 'llvm-mode)

+;; end of llvm-mode.el

diff --git a/src/LLVM/utils/emacs/tablegen-mode.el b/src/LLVM/utils/emacs/tablegen-mode.el
new file mode 100644
index 0000000..7989acf
--- /dev/null
+++ b/src/LLVM/utils/emacs/tablegen-mode.el
@@ -0,0 +1,124 @@
+;; Maintainer:  The LLVM team, http://llvm.org/

+;; Description: Major mode for TableGen description files (part of LLVM project)

+;; Updated:     2007-12-18

+

+(require 'comint)

+(require 'custom)

+(require 'ansi-color)

+

+;; Create mode-specific tables.

+(defvar td-decorators-face 'td-decorators-face

+  "Face method decorators.")

+(make-face 'td-decorators-face)

+

+(defvar tablegen-font-lock-keywords

+  (let ((kw (mapconcat 'identity

+                       '("class" "defm" "def" "field" "include" "in"

+                         "let" "multiclass")

+                       "\\|"))

+        (type-kw (mapconcat 'identity

+                            '("bit" "bits" "code" "dag" "int" "list" "string")

+                            "\\|"))

+        )

+    (list

+     ;; Comments

+;;     '("\/\/" . font-lock-comment-face)

+     ;; Strings

+     '("\"[^\"]+\"" . font-lock-string-face)

+     ;; Hex constants

+     '("\\<0x[0-9A-Fa-f]+\\>" . font-lock-preprocessor-face)

+     ;; Binary constants

+     '("\\<0b[01]+\\>" . font-lock-preprocessor-face)

+     ;; Integer literals

+     '("\\<[-]?[0-9]+\\>" . font-lock-preprocessor-face)

+     ;; Floating point constants

+     '("\\<[-+]?[0-9]+\.[0-9]*\([eE][-+]?[0-9]+\)?\\>" . font-lock-preprocessor-face)

+

+     '("^[ \t]*\\(@.+\\)" 1 'td-decorators-face)

+     ;; Keywords

+     (cons (concat "\\<\\(" kw "\\)\\>[ \n\t(]") 1)

+

+     ;; Type keywords

+     (cons (concat "\\<\\(" type-kw "\\)[ \n\t(]") 1)

+     ))

+  "Additional expressions to highlight in TableGen mode.")

+(put 'tablegen-mode 'font-lock-defaults '(tablegen-font-lock-keywords))

+

+;; ---------------------- Syntax table ---------------------------

+;; Shamelessly ripped from jasmin.el

+;; URL: http://www.neilvandyke.org/jasmin-emacs/jasmin.el

+

+(defvar tablegen-mode-syntax-table nil

+  "Syntax table used in `tablegen-mode' buffers.")

+(when (not tablegen-mode-syntax-table)

+  (setq tablegen-mode-syntax-table (make-syntax-table))

+  ;; whitespace (` ')

+  (modify-syntax-entry ?\   " "      tablegen-mode-syntax-table)

+  (modify-syntax-entry ?\t  " "      tablegen-mode-syntax-table)

+  (modify-syntax-entry ?\r  " "      tablegen-mode-syntax-table)

+  (modify-syntax-entry ?\n  " "      tablegen-mode-syntax-table)

+  (modify-syntax-entry ?\f  " "      tablegen-mode-syntax-table)

+  ;; word constituents (`w')

+  (modify-syntax-entry ?\%  "w"      tablegen-mode-syntax-table)

+  (modify-syntax-entry ?\_  "w"      tablegen-mode-syntax-table)

+  ;; comments

+  (modify-syntax-entry ?/   ". 124b" tablegen-mode-syntax-table)

+  (modify-syntax-entry ?*   ". 23"   tablegen-mode-syntax-table)

+  (modify-syntax-entry ?\n  "> b"    tablegen-mode-syntax-table)

+  ;; open paren (`(')

+  (modify-syntax-entry ?\(  "("      tablegen-mode-syntax-table)

+  (modify-syntax-entry ?\[  "("      tablegen-mode-syntax-table)

+  (modify-syntax-entry ?\{  "("      tablegen-mode-syntax-table)

+  (modify-syntax-entry ?\<  "("      tablegen-mode-syntax-table)

+  ;; close paren (`)')

+  (modify-syntax-entry ?\)  ")"      tablegen-mode-syntax-table)

+  (modify-syntax-entry ?\]  ")"      tablegen-mode-syntax-table)

+  (modify-syntax-entry ?\}  ")"      tablegen-mode-syntax-table)

+  (modify-syntax-entry ?\>  ")"      tablegen-mode-syntax-table)

+  ;; string quote ('"')

+  (modify-syntax-entry ?\"  "\""     tablegen-mode-syntax-table)

+  )

+

+;; --------------------- Abbrev table -----------------------------

+

+(defvar tablegen-mode-abbrev-table nil

+  "Abbrev table used while in TableGen mode.")

+(define-abbrev-table 'tablegen-mode-abbrev-table ())

+

+(defvar tablegen-mode-hook nil)

+(defvar tablegen-mode-map nil)   ; Create a mode-specific keymap.

+

+(if (not tablegen-mode-map)

+    ()  ; Do not change the keymap if it is already set up.

+  (setq tablegen-mode-map (make-sparse-keymap))

+  (define-key tablegen-mode-map "\t"  'tab-to-tab-stop)

+  (define-key tablegen-mode-map "\es" 'center-line)

+  (define-key tablegen-mode-map "\eS" 'center-paragraph))

+

+(defun tablegen-mode ()

+  "Major mode for editing TableGen description files.

+  \\{tablegen-mode-map}

+  Runs tablegen-mode-hook on startup."

+  (interactive)

+  (kill-all-local-variables)

+  (use-local-map tablegen-mode-map)      ; Provides the local keymap.

+  (make-local-variable 'font-lock-defaults)

+  (setq major-mode 'tablegen-mode        ; This is how describe-mode

+                                         ;   finds the doc string to print.

+	mode-name             "TableGen" ; This name goes into the modeline.

+        local-abbrev-table    tablegen-mode-abbrev-table

+	font-lock-defaults    `(tablegen-font-lock-keywords)

+	require-final-newline t

+        )

+

+  (set-syntax-table tablegen-mode-syntax-table)

+  (make-local-variable 'comment-start)

+  (setq comment-start "//")

+  (run-hooks 'tablegen-mode-hook))       ; Finally, this permits the user to

+                                         ;   customize the mode with a hook.

+

+;; Associate .td files with tablegen-mode

+(setq auto-mode-alist (append '(("\\.td$" . tablegen-mode)) auto-mode-alist))

+

+(provide 'tablegen-mode)

+;; end of tablegen-mode.el

diff --git a/src/LLVM/utils/findmisopt b/src/LLVM/utils/findmisopt
new file mode 100644
index 0000000..817004d
--- /dev/null
+++ b/src/LLVM/utils/findmisopt
@@ -0,0 +1,178 @@
+#!/bin/bash

+#

+#  findmisopt

+#

+#      This is a quick and dirty hack to potentially find a misoptimization

+#      problem. Mostly its to work around problems in bugpoint that prevent

+#      it from finding a problem unless the set of failing optimizations are

+#      known and given to it on the command line.

+#

+#      Given a bytecode file that produces correct output (or return code), 

+#      this script will run through all the optimizations passes that gccas

+#      uses (in the same order) and will narrow down which optimizations

+#      cause the program either generate different output or return a 

+#      different result code. When the passes have been narrowed down, 

+#      bugpoint is invoked to further refine the problem to its origin. If a

+#      release version of bugpoint is available it will be used, otherwise 

+#      debug.

+#

+#   Usage:

+#      findmisopt bcfile outdir progargs [match]

+#

+#   Where:

+#      bcfile 

+#          is the bytecode file input (the unoptimized working case)

+#      outdir

+#          is a directory into which intermediate results are placed

+#      progargs

+#          is a single argument containing all the arguments the program needs

+#      proginput

+#          is a file name from which stdin should be directed

+#      match

+#          if specified to any value causes the result code of the program to

+#          be used to determine success/fail. If not specified success/fail is

+#          determined by diffing the program's output with the non-optimized

+#          output.

+#       

+if [ "$#" -lt 3 ] ; then

+  echo "usage: findmisopt bcfile outdir progargs [match]"

+  exit 1

+fi

+

+dir="${0%%/utils/findmisopt}"

+if [ -x "$dir/Release/bin/bugpoint" ] ; then

+  bugpoint="$dir/Release/bin/bugpoint"

+elif [ -x "$dir/Debug/bin/bugpoint" ] ; then

+  bugpoint="$dir/Debug/bin/bugpoint"

+else

+  echo "findmisopt: bugpoint not found"

+  exit 1

+fi

+

+bcfile="$1"

+outdir="$2"

+args="$3"

+input="$4"

+if [ ! -f "$input" ] ; then

+  input="/dev/null"

+fi

+match="$5"

+name=`basename $bcfile .bc`

+ll="$outdir/${name}.ll"

+s="$outdir/${name}.s"

+prog="$outdir/${name}"

+out="$outdir/${name}.out"

+optbc="$outdir/${name}.opt.bc"

+optll="$outdir/${name}.opt.ll"

+opts="$outdir/${name}.opt.s"

+optprog="$outdir/${name}.opt"

+optout="$outdir/${name}.opt.out"

+ldflags="-lstdc++ -lm -ldl -lc"

+

+echo "Test Name: $name"

+echo "Unoptimized program: $prog"

+echo "  Optimized program: $optprog"

+

+# Define the list of optimizations to run. This comprises the same set of 

+# optimizations that opt -std-compile-opts and gccld run, in the same order.

+opt_switches=`llvm-as < /dev/null -o - | opt -std-compile-opts -disable-output -debug-pass=Arguments 2>&1 | sed 's/Pass Arguments: //'`

+ld_switches=`llvm-as < /dev/null -o - | llvm-ld - -debug-pass=Arguments 2>&1 | sed 's/Pass Arguments: //'`

+all_switches="$opt_switches $ld_switches"

+echo "Passes : $all_switches"

+

+# Create output directory if it doesn't exist

+if [ -f "$outdir" ] ; then

+  echo "$outdir is not a directory"

+  exit 1

+fi

+

+if [ ! -d "$outdir" ] ; then

+  mkdir "$outdir" || exit 1

+fi

+

+# Generate the disassembly

+llvm-dis "$bcfile" -o "$ll" -f || exit 1

+

+# Generate the non-optimized program and its output

+llc "$bcfile" -o "$s" -f || exit 1

+gcc "$s" -o "$prog" $ldflags || exit 1

+"$prog" $args > "$out" 2>&1 <$input

+ex1=$?

+

+# Current set of switches is empty

+function tryit {

+  switches_to_use="$1"

+  opt $switches_to_use "$bcfile" -o "$optbc" -f || exit

+  llvm-dis "$optbc" -o "$optll" -f || exit

+  llc "$optbc" -o "$opts" -f || exit

+  gcc "$opts" -o "$optprog" $ldflags || exit

+  "$optprog" $args > "$optout" 2>&1 <"$input"

+  ex2=$?

+

+  if [ -n "$match" ] ; then

+    if [ "$ex1" -ne "$ex2" ] ; then

+      echo "Return code not the same with these switches:"

+      echo $switches

+      echo "Unoptimized returned: $ex1"

+      echo "Optimized   returned: $ex2"

+      return 0

+    fi

+  else

+    diff "$out" "$optout" > /dev/null

+    if [ $? -ne 0 ] ; then

+      echo "Diff fails with these switches:"

+      echo $switches

+      echo "Differences:"

+      diff "$out" "$optout" | head

+      return 0;

+    fi

+  fi

+  return 1

+}

+

+echo "Trying to find optimization that breaks program:"

+for sw in $all_switches ; do

+  echo -n " $sw"

+  switches="$switches $sw"

+  if tryit "$switches" ; then

+    break;

+  fi

+done

+

+# Terminate the previous output with a newline

+echo ""

+

+# Determine if we're done because none of the optimizations broke the program

+if [ "$switches" == " $all_switches" ] ; then

+  echo "The program did not miscompile"

+  exit 0

+fi

+

+final=""

+while [ ! -z "$switches" ] ; do

+  trimmed=`echo "$switches" | sed -e 's/^ *\(-[^ ]*\).*/\1/'`

+  switches=`echo "$switches" | sed -e 's/^ *-[^ ]* *//'`

+  echo "Trimmed $trimmed from left"

+  tryit "$final $switches"

+  if [ "$?" -eq "0" ] ; then

+    echo "Still Failing .. continuing ..."

+    continue

+  else

+    echo "Found required early pass: $trimmed"

+    final="$final $trimmed"

+    continue

+  fi

+  echo "Next Loop"

+done

+

+if [ "$final" == " $all_switches" ] ; then

+  echo "findmisopt: All optimizations pass. Perhaps this isn't a misopt?"

+  exit 0

+fi

+echo "Smallest Optimization list=$final"

+

+bpcmd="$bugpoint -run-llc -disable-loop-extraction --output "$out" --input /dev/null $bcfile $final --args $args"

+

+echo "Running: $bpcmd"

+$bpcmd

+echo "findmisopt finished."

diff --git a/src/LLVM/utils/findoptdiff b/src/LLVM/utils/findoptdiff
new file mode 100644
index 0000000..e59dd3b
--- /dev/null
+++ b/src/LLVM/utils/findoptdiff
@@ -0,0 +1,101 @@
+#!/bin/bash

+#

+#  findoptdiff

+#

+#      This script helps find the optimization difference between two llvm

+#      builds. It is useful when you have a build that is known to work and

+#      one that exhibits an optimization problem. Identifying the difference

+#      between the two builds can lead to discovery of the source of a

+#      mis-optimization.

+#

+#      The script takes two llvm build paths as arguments. These specify the

+#      the two llvm builds to compare. It is generally expected that they

+#      are "close cousins".  That is, they are the same except that the 

+#      second build contains some experimental optimization features that

+#      are suspected of producing a misoptimization.

+#

+#      The script takes two bytecode files, one from each build. They are

+#      presumed to be a compilation of the same program or program fragment

+#      with the only difference being the builds.

+#

+#      The script operates by iteratively applying the optimizations that gccas

+#      and gccld run until there is a difference in the assembly resulting

+#      from the optimization. The difference is then reported with the set of

+#      optimization passes that produce the difference.  The processing 

+#      continues until all optimization passes have been tried. The differences

+#      for each pass, if they do differ, are placed in a diffs.# file.

+#

+#      To work around differences in the assembly language format, the script

+#      can also take two filter arguments that post-process the assembly 

+#      so they can be differenced without making false positives for known

+#      differences in the two builds. These filters are optional.

+#

+#   Usage:

+#      findoptdiff llvm1 llvm2 bc1 bc2 filter1 filter2

+#

+#   Where:

+#      llvm1

+#          is the path to the first llvm build dir

+#      llvm2

+#          is the path to the second llvm build dir

+#      bc1

+#          is the bytecode file for the first llvm environment

+#      bc2

+#          is the bytecode file for the second llvm environment

+#      filter1

+#          is an optional filter for filtering the llvm1 generated assembly

+#      filter2

+#          is an optional filter for filtering the llvm2 generated assembly

+#       

+llvm1=$1

+llvm2=$2

+bc1=$3

+bc2=$4

+filt1=$5

+filt2=$6

+if [ -z "$filt1" ] ; then

+  filt1="cat"

+fi

+if [ -z "$filt2" ] ; then

+  filt2="cat"

+fi

+opt1="${bc1}.opt"

+opt2="${bc2}.opt" 

+ll1="${bc1}.ll"

+ll2="${bc2}.ll"

+opt1ll="${bc1}.opt.ll"

+opt2ll="${bc2}.opt.ll"

+dis1="$llvm1/Debug/bin/llvm-dis"

+dis2="$llvm2/Debug/bin/llvm-dis"

+opt1="$llvm1/Debug/bin/opt"

+opt2="$llvm2/Debug/bin/opt"

+

+all_switches="-verify -lowersetjmp -simplifycfg -mem2reg -globalopt -globaldce -ipconstprop -deadargelim -instcombine -simplifycfg -prune-eh -inline -simplify-libcalls -argpromotion -tailduplicate -simplifycfg -scalarrepl -instcombine -predsimplify -condprop -tailcallelim -simplifycfg -reassociate -licm -loop-unswitch -instcombine -indvars -loop-unroll -instcombine -load-vn -gcse -sccp -instcombine -condprop -dse -dce -simplifycfg -deadtypeelim -constmerge -internalize -ipsccp -globalopt -constmerge -deadargelim -inline -prune-eh -globalopt -globaldce -argpromotion -instcombine -predsimplify -scalarrepl -globalsmodref-aa -licm -load-vn -gcse -dse -instcombine -simplifycfg -verify"

+

+#counter=0

+function tryit {

+  switches_to_use="$1"

+  $opt1 $switches_to_use "$bc1" -o - | $dis1 | $filt1 > "$opt1ll"

+  $opt2 $switches_to_use "$bc2" -o - | $dis2 | $filt2 > "$opt2ll"

+  diffs="diffs."$((counter++))

+  diff "$opt1ll" "$opt2ll" > $diffs

+  if [ $? -ne 0 ] ; then

+    echo

+    echo "Diff fails with these switches:"

+    echo $switches

+    echo "Differences:"

+    head $diffs

+    echo 'Switches:' $switches_to_use >> $diffs

+  else

+    rm $diffs

+  fi

+  return 1

+}

+

+for sw in $all_switches ; do

+  echo -n " $sw"

+  switches="$switches $sw"

+  if tryit "$switches" ; then

+    break;

+  fi

+done

diff --git a/src/LLVM/utils/findsym.pl b/src/LLVM/utils/findsym.pl
new file mode 100644
index 0000000..9234657
--- /dev/null
+++ b/src/LLVM/utils/findsym.pl
@@ -0,0 +1,33 @@
+#!/usr/bin/perl -w
+#
+# Program:  findsym.pl
+#
+# Synopsis: Generate a list of the libraries in which a symbol is defined or
+#           referenced.
+#
+# Syntax:   findsym.pl <directory_with_libraries_in_it> <symbol>
+#
+
+# Give first option a name.
+my $Directory = $ARGV[0];
+my $Symbol = $ARGV[1];
+
+# Open the directory and read its contents, sorting by name and differentiating
+# by whether its a library (.a) or an object file (.o)
+opendir DIR,$Directory;
+my @files = readdir DIR;
+closedir DIR;
+@objects = grep(/l?i?b?LLVM.*\.[oa]$/,sort(@files));
+
+# Gather definitions from the libraries
+foreach $lib (@objects) {
+  my $head = 0;
+  open SYMS, 
+    "nm $Directory/$lib | grep '$Symbol' | sort --key=3 | uniq |";
+  while (<SYMS>) {
+    if (!$head) { print "$lib:\n"; $head = 1; }
+    chomp($_);
+    print "  $_\n";
+  }
+  close SYMS;
+}
diff --git a/src/LLVM/utils/fpcmp/Makefile b/src/LLVM/utils/fpcmp/Makefile
new file mode 100644
index 0000000..fd2f747
--- /dev/null
+++ b/src/LLVM/utils/fpcmp/Makefile
@@ -0,0 +1,16 @@
+##===- utils/fpcmp/Makefile --------------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+TOOLNAME = fpcmp
+USEDLIBS = LLVMSupport.a LLVMSystem.a
+NO_INSTALL = 1
+
+include $(LEVEL)/Makefile.common
+
diff --git a/src/LLVM/utils/fpcmp/fpcmp.cpp b/src/LLVM/utils/fpcmp/fpcmp.cpp
new file mode 100644
index 0000000..5f6b5e8
--- /dev/null
+++ b/src/LLVM/utils/fpcmp/fpcmp.cpp
@@ -0,0 +1,43 @@
+//===- fpcmp.cpp - A fuzzy "cmp" that permits floating point noise --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// fpcmp is a tool that basically works like the 'cmp' tool, except that it can
+// tolerate errors due to floating point noise, with the -r and -a options.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+namespace {
+  cl::opt<std::string>
+  File1(cl::Positional, cl::desc("<input file #1>"), cl::Required);
+  cl::opt<std::string>
+  File2(cl::Positional, cl::desc("<input file #2>"), cl::Required);
+
+  cl::opt<double>
+  RelTolerance("r", cl::desc("Relative error tolerated"), cl::init(0));
+  cl::opt<double>
+  AbsTolerance("a", cl::desc("Absolute error tolerated"), cl::init(0));
+}
+
+int main(int argc, char **argv) {
+  cl::ParseCommandLineOptions(argc, argv);
+
+  std::string ErrorMsg;
+  int DF = DiffFilesWithTolerance(sys::PathWithStatus(File1), 
+                                  sys::PathWithStatus(File2),
+                                  AbsTolerance, RelTolerance, &ErrorMsg);
+  if (!ErrorMsg.empty())
+    errs() << argv[0] << ": " << ErrorMsg << "\n";
+  return DF;
+}
+
diff --git a/src/LLVM/utils/getsrcs.sh b/src/LLVM/utils/getsrcs.sh
new file mode 100644
index 0000000..c8bff8c
--- /dev/null
+++ b/src/LLVM/utils/getsrcs.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+##===- utils/getsrcs.sh - Counts Lines Of Code ---------------*- Script -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# details.
+# 
+##===----------------------------------------------------------------------===##
+#
+# This script just prints out the path names for all the source files in LLVM.
+# The optional -topdir option can be used to specify the top LLVM source 
+# directory. Without it, the llvm-config command is consulted to find the
+# top source directory.
+#
+# Note that the implementation is based on llvmdo. See that script for more
+# details.
+##===----------------------------------------------------------------------===##
+
+if test "$1" = "-topdir" ; then
+  TOPDIR="$2"
+  shift; shift;
+else
+  TOPDIR=`llvm-config --src-root`
+fi
+
+if test -d "$TOPDIR" ; then
+  cd $TOPDIR
+  ./utils/llvmdo -topdir "$TOPDIR" \
+    -dirs "include lib tools utils examples projects" echo
+else
+  echo "Can't find LLVM top directory"
+fi
diff --git a/src/LLVM/utils/importNLT.pl b/src/LLVM/utils/importNLT.pl
new file mode 100644
index 0000000..c1b950d
--- /dev/null
+++ b/src/LLVM/utils/importNLT.pl
@@ -0,0 +1,86 @@
+#!/usr/bin/perl
+#take the output of parseNLT.pl and load it into a database
+# use like: cat file |perl parseNLT.pl |perl importNLT.pl password
+
+use DBI;
+
+# database information
+$db="llvmalpha";
+$host="localhost";
+$userid="llvmdbuser";
+$passwd=shift @ARGV;
+$connectionInfo="dbi:mysql:$db;$host";
+
+# make connection to database
+$dbh = DBI->connect($connectionInfo,$userid,$passwd) or die DBI->errstr;
+my $sth = $dbh->prepare( q{
+      INSERT INTO Tests (NAME, RUN, TEST, VALUE) VALUES (?, STR_TO_DATE(?, '\%d \%M \%Y'), ?, ?)
+  }) || die "Can't prepare statement: $DBI::errstr";;
+
+while($d = <>)
+{
+  chomp $d;
+  if (18 == scalar split " ", $d)
+    {
+      ($day, $mon, $year, $prog, $gccas, $bc, $llccompile, $llcbetacompile, $jitcompile,
+       $mc, $gcc, $cbe, $llc, $llcbeta, $jit, $foo1, $foo2, $foo3) = split " ", $d;
+      if ($gccas =~ /\d+/)
+        {
+          $dbh->do("INSERT INTO Tests (NAME, RUN, TEST, VALUE) VALUES
+                ('$prog', STR_TO_DATE('$day $mon $year', '\%d \%M \%Y'), 'gccas', $gccas)") || die DBI->errstr;
+        }
+      if ($bc =~ /\d/)
+        {
+          $dbh->do("INSERT INTO Tests (NAME, RUN, TEST, VALUE) VALUES
+                ('$prog', STR_TO_DATE('$day $mon $year', '\%d \%M \%Y'), 'bytecode', $bc)") || die DBI->errstr;
+        }
+      if ($llccompile =~ /\d/)
+        {
+          $dbh->do("INSERT INTO Tests (NAME, RUN, TEST, VALUE) VALUES
+                ('$prog', STR_TO_DATE('$day $mon $year', '\%d \%M \%Y'), 'llc-compile', $llccompile)") || die DBI->errstr;
+        }
+      if ($llcbetacompile =~ /\d/)
+        {
+          $dbh->do("INSERT INTO Tests (NAME, RUN, TEST, VALUE) VALUES
+                ('$prog', STR_TO_DATE('$day $mon $year', '\%d \%M \%Y'), 'llc-beta-compile', $llcbetacompile)") || die DBI->errstr;
+        }
+      if ($jitcompile =~ /\d/)
+        {
+          $dbh->do("INSERT INTO Tests (NAME, RUN, TEST, VALUE) VALUES
+                ('$prog', STR_TO_DATE('$day $mon $year', '\%d \%M \%Y'), 'jit-compile', $jitcompile)") || die DBI->errstr;
+        }
+      if ($mc =~ /\d/)
+        {
+          $dbh->do("INSERT INTO Tests (NAME, RUN, TEST, VALUE) VALUES
+                ('$prog', STR_TO_DATE('$day $mon $year', '\%d \%M \%Y'), 'machine-code', $mc)") || die DBI->errstr;
+        }
+      if ($gcc =~ /\d/)
+        {
+          $dbh->do("INSERT INTO Tests (NAME, RUN, TEST, VALUE) VALUES
+                ('$prog', STR_TO_DATE('$day $mon $year', '\%d \%M \%Y'), 'gcc', $gcc)") || die DBI->errstr;
+        }
+      if ($llc =~ /\d/)
+        {
+          $dbh->do("INSERT INTO Tests (NAME, RUN, TEST, VALUE) VALUES
+                ('$prog', STR_TO_DATE('$day $mon $year', '\%d \%M \%Y'), 'llc', $llc)") || die DBI->errstr;
+        }
+      if ($llcbeta =~ /\d/)
+        {
+          $dbh->do("INSERT INTO Tests (NAME, RUN, TEST, VALUE) VALUES
+                ('$prog', STR_TO_DATE('$day $mon $year', '\%d \%M \%Y'), 'llc-beta', $llcbeta)") || die DBI->errstr;
+        }
+      if ($jit =~ /\d/)
+        {
+          $dbh->do("INSERT INTO Tests (NAME, RUN, TEST, VALUE) VALUES
+                ('$prog', STR_TO_DATE('$day $mon $year', '\%d \%M \%Y'), 'jit', $jit)") || die DBI->errstr;
+        }
+      print ".";
+    }
+  else
+    {
+      print "\nNO: $d\n";
+    }
+}
+print "\n";
+# disconnect from database
+$dbh->disconnect;
diff --git a/src/LLVM/utils/jedit/README b/src/LLVM/utils/jedit/README
new file mode 100644
index 0000000..6a6c8c7
--- /dev/null
+++ b/src/LLVM/utils/jedit/README
@@ -0,0 +1,14 @@
+-*- llvm/utils/jedit/README -*-
+
+These are syntax highlighting files for the jEdit editor. Included are:
+
+* tablegen.xml
+
+  Syntax highlighting mode for TableGen description files. To use, copy this
+  file to ~/.jedit/modes/ and add this code to your ~/.jedit/modes/catalog:
+
+  <MODE NAME="tablegen" FILE="tablegen.xml" FILE_NAME_GLOB="*.td" />
+
+Note: If you notice missing or incorrect syntax highlighting, please contact
+<llvmbugs [at] cs.uiuc.edu>; if you wish to provide a patch to improve the
+functionality, it will be most appreciated. Thank you.
diff --git a/src/LLVM/utils/jedit/tablegen.xml b/src/LLVM/utils/jedit/tablegen.xml
new file mode 100644
index 0000000..2d80a3f
--- /dev/null
+++ b/src/LLVM/utils/jedit/tablegen.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<!DOCTYPE MODE SYSTEM "xmode.dtd">
+<MODE>
+	<PROPS>
+		<PROPERTY NAME="lineComment" VALUE="//" />
+		<PROPERTY NAME="commentStart" VALUE="/*" />
+		<PROPERTY NAME="commentEnd" VALUE="*/" />
+		<PROPERTY NAME="indentOpenBrackets" VALUE="{" />
+		<PROPERTY NAME="indentCloseBrackets" VALUE="}" />
+		<PROPERTY NAME="wordBreakChars" VALUE=",+-=&lt;&gt;/?^&amp;*" />
+		<PROPERTY NAME="unalignedOpenBrackets" VALUE="(&lt;" />
+		<PROPERTY NAME="unalignedCloseBrackets" VALUE=")&gt;" />
+	</PROPS>
+	<RULES IGNORE_CASE="FALSE" HIGHLIGHT_DIGITS="TRUE">
+		<EOL_SPAN TYPE="COMMENT1">//</EOL_SPAN>
+		<SPAN TYPE="COMMENT1">
+		    <BEGIN>/*</BEGIN>
+		    <END>*/</END>
+		</SPAN>
+		<SPAN TYPE="LITERAL1" NO_LINE_BREAK="TRUE" ESCAPE="\">
+		    <BEGIN>"</BEGIN>
+		    <END>"</END>
+		</SPAN>
+		<KEYWORDS>
+			<KEYWORD1>let</KEYWORD1>
+			<KEYWORD1>def</KEYWORD1>
+			<KEYWORD1>class</KEYWORD1>
+			<KEYWORD1>include</KEYWORD1>
+
+			<KEYWORD3>bit</KEYWORD3>
+			<KEYWORD3>int</KEYWORD3>
+			<KEYWORD3>string</KEYWORD3>
+			<KEYWORD3>bits</KEYWORD3>
+			<KEYWORD3>list</KEYWORD3>
+			<KEYWORD3>dag</KEYWORD3>
+			<KEYWORD3>code</KEYWORD3>
+		</KEYWORDS>
+	</RULES>
+</MODE>
diff --git a/src/LLVM/utils/lint/common_lint.py b/src/LLVM/utils/lint/common_lint.py
new file mode 100644
index 0000000..e982680
--- /dev/null
+++ b/src/LLVM/utils/lint/common_lint.py
@@ -0,0 +1,97 @@
+#!/usr/bin/python
+#
+# Common lint functions applicable to multiple types of files.
+
+import re
+
+def VerifyLineLength(filename, lines, max_length):
+  """Checks to make sure the file has no lines with lines exceeding the length
+  limit.
+
+  Args:
+    filename: the file under consideration as string
+    lines: contents of the file as string array
+    max_length: maximum acceptable line length as number
+
+  Returns:
+    A list of tuples with format [(filename, line number, msg), ...] with any
+    violations found.
+  """
+  lint = []
+  line_num = 1
+  for line in lines:
+    length = len(line.rstrip('\n'))
+    if length > max_length:
+      lint.append((filename, line_num,
+                   'Line exceeds %d chars (%d)' % (max_length, length)))
+    line_num += 1
+  return lint
+
+def VerifyTabs(filename, lines):
+  """Checks to make sure the file has no tab characters.
+
+  Args:
+    filename: the file under consideration as string
+    lines: contents of the file as string array
+
+  Returns:
+    A list of tuples with format [(line_number, msg), ...] with any violations
+    found.
+  """
+  lint = []
+  tab_re = re.compile(r'\t')
+  line_num = 1
+  for line in lines:
+    if tab_re.match(line.rstrip('\n')):
+      lint.append((filename, line_num, 'Tab found instead of whitespace'))
+    line_num += 1
+  return lint
+
+
+def VerifyTrailingWhitespace(filename, lines):
+  """Checks to make sure the file has no lines with trailing whitespace.
+
+  Args:
+    filename: the file under consideration as string
+    lines: contents of the file as string array
+
+  Returns:
+    A list of tuples with format [(filename, line number, msg), ...] with any
+    violations found.
+  """
+  lint = []
+  trailing_whitespace_re = re.compile(r'\s+$')
+  line_num = 1
+  for line in lines:
+    if trailing_whitespace_re.match(line.rstrip('\n')):
+      lint.append((filename, line_num, 'Trailing whitespace'))
+    line_num += 1
+  return lint
+
+
+class BaseLint:
+  def RunOnFile(filename, lines):
+    raise Exception('RunOnFile() unimplemented')
+
+
+def RunLintOverAllFiles(linter, filenames):
+  """Runs linter over the contents of all files.
+
+  Args:
+    lint: subclass of BaseLint, implementing RunOnFile()
+    filenames: list of all files whose contents will be linted
+
+  Returns:
+    A list of tuples with format [(filename, line number, msg), ...] with any
+    violations found.
+  """
+  lint = []
+  for filename in filenames:
+    file = open(filename, 'r')
+    if not file:
+      print 'Cound not open %s' % filename
+      continue
+    lines = file.readlines()
+    lint.extend(linter.RunOnFile(filename, lines))
+
+  return lint
diff --git a/src/LLVM/utils/lint/cpp_lint.py b/src/LLVM/utils/lint/cpp_lint.py
new file mode 100644
index 0000000..07fad58
--- /dev/null
+++ b/src/LLVM/utils/lint/cpp_lint.py
@@ -0,0 +1,94 @@
+#!/usr/bin/python
+#
+# Checks C++ files to make sure they conform to LLVM standards, as specified in
+# http://llvm.org/docs/CodingStandards.html .
+#
+# TODO: add unittests for the verifier functions:
+# http://docs.python.org/library/unittest.html .
+
+import common_lint
+import re
+import sys
+
+def VerifyIncludes(filename, lines):
+  """Makes sure the #includes are in proper order and no disallows files are
+  #included.
+
+  Args:
+    filename: the file under consideration as string
+    lines: contents of the file as string array
+  """
+  lint = []
+
+  include_gtest_re = re.compile(r'^#include "gtest/(.*)"')
+  include_llvm_re = re.compile(r'^#include "llvm/(.*)"')
+  include_support_re = re.compile(r'^#include "(Support/.*)"')
+  include_config_re = re.compile(r'^#include "(Config/.*)"')
+  include_system_re = re.compile(r'^#include <(.*)>')
+
+  DISALLOWED_SYSTEM_HEADERS = ['iostream']
+
+  line_num = 1
+  prev_config_header = None
+  prev_system_header = None
+  for line in lines:
+    # TODO: implement private headers
+    # TODO: implement gtest headers
+    # TODO: implement top-level llvm/* headers
+    # TODO: implement llvm/Support/* headers
+
+    # Process Config/* headers
+    config_header = include_config_re.match(line)
+    if config_header:
+      curr_config_header = config_header.group(1)
+      if prev_config_header:
+        if prev_config_header > curr_config_header:
+          lint.append((filename, line_num,
+                       'Config headers not in order: "%s" before "%s"' % (
+                         prev_config_header, curr_config_header)))
+
+    # Process system headers
+    system_header = include_system_re.match(line)
+    if system_header:
+      curr_system_header = system_header.group(1)
+
+      # Is it blacklisted?
+      if curr_system_header in DISALLOWED_SYSTEM_HEADERS:
+        lint.append((filename, line_num,
+                     'Disallowed system header: <%s>' % curr_system_header))
+      elif prev_system_header:
+        # Make sure system headers are alphabetized amongst themselves
+        if prev_system_header > curr_system_header:
+          lint.append((filename, line_num,
+                       'System headers not in order: <%s> before <%s>' % (
+                         prev_system_header, curr_system_header)))
+
+      prev_system_header = curr_system_header
+
+    line_num += 1
+
+  return lint
+
+
+class CppLint(common_lint.BaseLint):
+  MAX_LINE_LENGTH = 80
+
+  def RunOnFile(self, filename, lines):
+    lint = []
+    lint.extend(VerifyIncludes(filename, lines))
+    lint.extend(common_lint.VerifyLineLength(filename, lines,
+                                             CppLint.MAX_LINE_LENGTH))
+    lint.extend(common_lint.VerifyTabs(filename, lines))
+    lint.extend(common_lint.VerifyTrailingWhitespace(filename, lines))
+    return lint
+
+
+def CppLintMain(filenames):
+  all_lint = common_lint.RunLintOverAllFiles(CppLint(), filenames)
+  for lint in all_lint:
+    print '%s:%d:%s' % (lint[0], lint[1], lint[2])
+  return 0
+
+
+if __name__ == '__main__':
+  sys.exit(CppLintMain(sys.argv[1:]))
diff --git a/src/LLVM/utils/lint/generic_lint.py b/src/LLVM/utils/lint/generic_lint.py
new file mode 100644
index 0000000..c8f4835
--- /dev/null
+++ b/src/LLVM/utils/lint/generic_lint.py
@@ -0,0 +1,24 @@
+#!/usr/bin/python
+#
+# Checks files to make sure they conform to LLVM standards which can be applied
+# to any programming language: at present, line length and trailing whitespace.
+
+import common_lint
+import sys
+
+class GenericCodeLint(common_lint.BaseLint):
+  MAX_LINE_LENGTH = 80
+
+  def RunOnFile(self, filename, lines):
+    common_lint.VerifyLineLength(filename, lines,
+                                 GenericCodeLint.MAX_LINE_LENGTH)
+    common_lint.VerifyTrailingWhitespace(filename, lines)
+
+
+def GenericCodeLintMain(filenames):
+  common_lint.RunLintOverAllFiles(GenericCodeLint(), filenames)
+  return 0
+
+
+if __name__ == '__main__':
+  sys.exit(GenericCodeLintMain(sys.argv[1:]))
diff --git a/src/LLVM/utils/lint/remove_trailing_whitespace.sh b/src/LLVM/utils/lint/remove_trailing_whitespace.sh
new file mode 100644
index 0000000..6e0c9be
--- /dev/null
+++ b/src/LLVM/utils/lint/remove_trailing_whitespace.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+# Deletes trailing whitespace in-place in the passed-in files.
+# Sample syntax:
+#   $0 *.cpp
+
+perl -pi -e 's/\s+$/\n/' $*
diff --git a/src/LLVM/utils/lit/LitConfig.py b/src/LLVM/utils/lit/LitConfig.py
new file mode 100644
index 0000000..0e0a493
--- /dev/null
+++ b/src/LLVM/utils/lit/LitConfig.py
@@ -0,0 +1,95 @@
+class LitConfig:
+    """LitConfig - Configuration data for a 'lit' test runner instance, shared
+    across all tests.
+
+    The LitConfig object is also used to communicate with client configuration
+    files, it is always passed in as the global variable 'lit' so that
+    configuration files can access common functionality and internal components
+    easily.
+    """
+
+    # Provide access to built-in formats.
+    import LitFormats as formats
+
+    # Provide access to built-in utility functions.
+    import Util as util
+
+    def __init__(self, progname, path, quiet,
+                 useValgrind, valgrindArgs,
+                 useTclAsSh,
+                 noExecute, debug, isWindows,
+                 params):
+        # The name of the test runner.
+        self.progname = progname
+        # The items to add to the PATH environment variable.
+        self.path = list(map(str, path))
+        self.quiet = bool(quiet)
+        self.useValgrind = bool(useValgrind)
+        self.valgrindArgs = list(valgrindArgs)
+        self.useTclAsSh = bool(useTclAsSh)
+        self.noExecute = noExecute
+        self.debug = debug
+        self.isWindows = bool(isWindows)
+        self.params = dict(params)
+        self.bashPath = None
+
+        self.numErrors = 0
+        self.numWarnings = 0
+
+    def load_config(self, config, path):
+        """load_config(config, path) - Load a config object from an alternate
+        path."""
+        from TestingConfig import TestingConfig
+        return TestingConfig.frompath(path, config.parent, self,
+                                      mustExist = True,
+                                      config = config)
+
+    def getBashPath(self):
+        """getBashPath - Get the path to 'bash'"""
+        import os, Util
+
+        if self.bashPath is not None:
+            return self.bashPath
+
+        self.bashPath = Util.which('bash', os.pathsep.join(self.path))
+        if self.bashPath is None:
+            # Check some known paths.
+            for path in ('/bin/bash', '/usr/bin/bash'):
+                if os.path.exists(path):
+                    self.bashPath = path
+                    break
+
+        if self.bashPath is None:
+            self.warning("Unable to find 'bash', running Tcl tests internally.")
+            self.bashPath = ''
+
+        return self.bashPath
+
+    def _write_message(self, kind, message):
+        import inspect, os, sys
+
+        # Get the file/line where this message was generated.
+        f = inspect.currentframe()
+        # Step out of _write_message, and then out of wrapper.
+        f = f.f_back.f_back
+        file,line,_,_,_ = inspect.getframeinfo(f)
+        location = '%s:%d' % (os.path.basename(file), line)
+
+        print >>sys.stderr, '%s: %s: %s: %s' % (self.progname, location,
+                                                kind, message)
+
+    def note(self, message):
+        self._write_message('note', message)
+
+    def warning(self, message):
+        self._write_message('warning', message)
+        self.numWarnings += 1
+
+    def error(self, message):
+        self._write_message('error', message)
+        self.numErrors += 1
+
+    def fatal(self, message):
+        import sys
+        self._write_message('fatal', message)
+        sys.exit(2)
diff --git a/src/LLVM/utils/lit/LitFormats.py b/src/LLVM/utils/lit/LitFormats.py
new file mode 100644
index 0000000..270f087
--- /dev/null
+++ b/src/LLVM/utils/lit/LitFormats.py
@@ -0,0 +1,3 @@
+from TestFormats import GoogleTest, ShTest, TclTest
+from TestFormats import SyntaxCheckTest, OneCommandPerFileTest
+
diff --git a/src/LLVM/utils/lit/ProgressBar.py b/src/LLVM/utils/lit/ProgressBar.py
new file mode 100644
index 0000000..85c95f5
--- /dev/null
+++ b/src/LLVM/utils/lit/ProgressBar.py
@@ -0,0 +1,267 @@
+#!/usr/bin/env python
+
+# Source: http://code.activestate.com/recipes/475116/, with
+# modifications by Daniel Dunbar.
+
+import sys, re, time
+
+class TerminalController:
+    """
+    A class that can be used to portably generate formatted output to
+    a terminal.  
+    
+    `TerminalController` defines a set of instance variables whose
+    values are initialized to the control sequence necessary to
+    perform a given action.  These can be simply included in normal
+    output to the terminal:
+
+        >>> term = TerminalController()
+        >>> print 'This is '+term.GREEN+'green'+term.NORMAL
+
+    Alternatively, the `render()` method can used, which replaces
+    '${action}' with the string required to perform 'action':
+
+        >>> term = TerminalController()
+        >>> print term.render('This is ${GREEN}green${NORMAL}')
+
+    If the terminal doesn't support a given action, then the value of
+    the corresponding instance variable will be set to ''.  As a
+    result, the above code will still work on terminals that do not
+    support color, except that their output will not be colored.
+    Also, this means that you can test whether the terminal supports a
+    given action by simply testing the truth value of the
+    corresponding instance variable:
+
+        >>> term = TerminalController()
+        >>> if term.CLEAR_SCREEN:
+        ...     print 'This terminal supports clearning the screen.'
+
+    Finally, if the width and height of the terminal are known, then
+    they will be stored in the `COLS` and `LINES` attributes.
+    """
+    # Cursor movement:
+    BOL = ''             #: Move the cursor to the beginning of the line
+    UP = ''              #: Move the cursor up one line
+    DOWN = ''            #: Move the cursor down one line
+    LEFT = ''            #: Move the cursor left one char
+    RIGHT = ''           #: Move the cursor right one char
+
+    # Deletion:
+    CLEAR_SCREEN = ''    #: Clear the screen and move to home position
+    CLEAR_EOL = ''       #: Clear to the end of the line.
+    CLEAR_BOL = ''       #: Clear to the beginning of the line.
+    CLEAR_EOS = ''       #: Clear to the end of the screen
+
+    # Output modes:
+    BOLD = ''            #: Turn on bold mode
+    BLINK = ''           #: Turn on blink mode
+    DIM = ''             #: Turn on half-bright mode
+    REVERSE = ''         #: Turn on reverse-video mode
+    NORMAL = ''          #: Turn off all modes
+
+    # Cursor display:
+    HIDE_CURSOR = ''     #: Make the cursor invisible
+    SHOW_CURSOR = ''     #: Make the cursor visible
+
+    # Terminal size:
+    COLS = None          #: Width of the terminal (None for unknown)
+    LINES = None         #: Height of the terminal (None for unknown)
+
+    # Foreground colors:
+    BLACK = BLUE = GREEN = CYAN = RED = MAGENTA = YELLOW = WHITE = ''
+    
+    # Background colors:
+    BG_BLACK = BG_BLUE = BG_GREEN = BG_CYAN = ''
+    BG_RED = BG_MAGENTA = BG_YELLOW = BG_WHITE = ''
+    
+    _STRING_CAPABILITIES = """
+    BOL=cr UP=cuu1 DOWN=cud1 LEFT=cub1 RIGHT=cuf1
+    CLEAR_SCREEN=clear CLEAR_EOL=el CLEAR_BOL=el1 CLEAR_EOS=ed BOLD=bold
+    BLINK=blink DIM=dim REVERSE=rev UNDERLINE=smul NORMAL=sgr0
+    HIDE_CURSOR=cinvis SHOW_CURSOR=cnorm""".split()
+    _COLORS = """BLACK BLUE GREEN CYAN RED MAGENTA YELLOW WHITE""".split()
+    _ANSICOLORS = "BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE".split()
+
+    def __init__(self, term_stream=sys.stdout):
+        """
+        Create a `TerminalController` and initialize its attributes
+        with appropriate values for the current terminal.
+        `term_stream` is the stream that will be used for terminal
+        output; if this stream is not a tty, then the terminal is
+        assumed to be a dumb terminal (i.e., have no capabilities).
+        """
+        # Curses isn't available on all platforms
+        try: import curses
+        except: return
+
+        # If the stream isn't a tty, then assume it has no capabilities.
+        if not term_stream.isatty(): return
+
+        # Check the terminal type.  If we fail, then assume that the
+        # terminal has no capabilities.
+        try: curses.setupterm()
+        except: return
+
+        # Look up numeric capabilities.
+        self.COLS = curses.tigetnum('cols')
+        self.LINES = curses.tigetnum('lines')
+        
+        # Look up string capabilities.
+        for capability in self._STRING_CAPABILITIES:
+            (attrib, cap_name) = capability.split('=')
+            setattr(self, attrib, self._tigetstr(cap_name) or '')
+
+        # Colors
+        set_fg = self._tigetstr('setf')
+        if set_fg:
+            for i,color in zip(range(len(self._COLORS)), self._COLORS):
+                setattr(self, color, curses.tparm(set_fg, i) or '')
+        set_fg_ansi = self._tigetstr('setaf')
+        if set_fg_ansi:
+            for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS):
+                setattr(self, color, curses.tparm(set_fg_ansi, i) or '')
+        set_bg = self._tigetstr('setb')
+        if set_bg:
+            for i,color in zip(range(len(self._COLORS)), self._COLORS):
+                setattr(self, 'BG_'+color, curses.tparm(set_bg, i) or '')
+        set_bg_ansi = self._tigetstr('setab')
+        if set_bg_ansi:
+            for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS):
+                setattr(self, 'BG_'+color, curses.tparm(set_bg_ansi, i) or '')
+
+    def _tigetstr(self, cap_name):
+        # String capabilities can include "delays" of the form "$<2>".
+        # For any modern terminal, we should be able to just ignore
+        # these, so strip them out.
+        import curses
+        cap = curses.tigetstr(cap_name) or ''
+        return re.sub(r'\$<\d+>[/*]?', '', cap)
+
+    def render(self, template):
+        """
+        Replace each $-substitutions in the given template string with
+        the corresponding terminal control string (if it's defined) or
+        '' (if it's not).
+        """
+        return re.sub(r'\$\$|\${\w+}', self._render_sub, template)
+
+    def _render_sub(self, match):
+        s = match.group()
+        if s == '$$': return s
+        else: return getattr(self, s[2:-1])
+
+#######################################################################
+# Example use case: progress bar
+#######################################################################
+
+class SimpleProgressBar:
+    """
+    A simple progress bar which doesn't need any terminal support.
+
+    This prints out a progress bar like:
+      'Header: 0 .. 10.. 20.. ...'
+    """
+
+    def __init__(self, header):
+        self.header = header
+        self.atIndex = None
+
+    def update(self, percent, message):
+        if self.atIndex is None:
+            sys.stdout.write(self.header)
+            self.atIndex = 0
+
+        next = int(percent*50)
+        if next == self.atIndex:
+            return
+
+        for i in range(self.atIndex, next):
+            idx = i % 5
+            if idx == 0:
+                sys.stdout.write('%-2d' % (i*2))
+            elif idx == 1:
+                pass # Skip second char
+            elif idx < 4:
+                sys.stdout.write('.')
+            else:
+                sys.stdout.write(' ')
+        sys.stdout.flush()
+        self.atIndex = next
+
+    def clear(self):
+        if self.atIndex is not None:
+            sys.stdout.write('\n')
+            sys.stdout.flush()
+            self.atIndex = None
+
+class ProgressBar:
+    """
+    A 3-line progress bar, which looks like::
+    
+                                Header
+        20% [===========----------------------------------]
+                           progress message
+
+    The progress bar is colored, if the terminal supports color
+    output; and adjusts to the width of the terminal.
+    """
+    BAR = '%s${GREEN}[${BOLD}%s%s${NORMAL}${GREEN}]${NORMAL}%s\n'
+    HEADER = '${BOLD}${CYAN}%s${NORMAL}\n\n'
+        
+    def __init__(self, term, header, useETA=True):
+        self.term = term
+        if not (self.term.CLEAR_EOL and self.term.UP and self.term.BOL):
+            raise ValueError("Terminal isn't capable enough -- you "
+                             "should use a simpler progress dispaly.")
+        self.width = self.term.COLS or 75
+        self.bar = term.render(self.BAR)
+        self.header = self.term.render(self.HEADER % header.center(self.width))
+        self.cleared = 1 #: true if we haven't drawn the bar yet.
+        self.useETA = useETA
+        if self.useETA:
+            self.startTime = time.time()
+        self.update(0, '')
+
+    def update(self, percent, message):
+        if self.cleared:
+            sys.stdout.write(self.header)
+            self.cleared = 0
+        prefix = '%3d%% ' % (percent*100,)
+        suffix = ''
+        if self.useETA:
+            elapsed = time.time() - self.startTime
+            if percent > .0001 and elapsed > 1:
+                total = elapsed / percent
+                eta = int(total - elapsed)
+                h = eta//3600.
+                m = (eta//60) % 60
+                s = eta % 60
+                suffix = ' ETA: %02d:%02d:%02d'%(h,m,s)
+        barWidth = self.width - len(prefix) - len(suffix) - 2
+        n = int(barWidth*percent)
+        if len(message) < self.width:
+            message = message + ' '*(self.width - len(message))
+        else:
+            message = '... ' + message[-(self.width-4):]
+        sys.stdout.write(
+            self.term.BOL + self.term.UP + self.term.CLEAR_EOL +
+            (self.bar % (prefix, '='*n, '-'*(barWidth-n), suffix)) +
+            self.term.CLEAR_EOL + message)
+
+    def clear(self):
+        if not self.cleared:
+            sys.stdout.write(self.term.BOL + self.term.CLEAR_EOL +
+                             self.term.UP + self.term.CLEAR_EOL +
+                             self.term.UP + self.term.CLEAR_EOL)
+            self.cleared = 1
+
+def test():
+    import time
+    tc = TerminalController()
+    p = ProgressBar(tc, 'Tests')
+    for i in range(101):
+        p.update(i/100., str(i))        
+        time.sleep(.3)
+
+if __name__=='__main__':
+    test()
diff --git a/src/LLVM/utils/lit/ShCommands.py b/src/LLVM/utils/lit/ShCommands.py
new file mode 100644
index 0000000..4550437
--- /dev/null
+++ b/src/LLVM/utils/lit/ShCommands.py
@@ -0,0 +1,85 @@
+class Command:
+    def __init__(self, args, redirects):
+        self.args = list(args)
+        self.redirects = list(redirects)
+
+    def __repr__(self):
+        return 'Command(%r, %r)' % (self.args, self.redirects)
+
+    def __cmp__(self, other):
+        if not isinstance(other, Command):
+            return -1
+
+        return cmp((self.args, self.redirects),
+                   (other.args, other.redirects))
+
+    def toShell(self, file):
+        for arg in self.args:
+            if "'" not in arg:
+                quoted = "'%s'" % arg
+            elif '"' not in arg and '$' not in arg:
+                quoted = '"%s"' % arg
+            else:
+                raise NotImplementedError,'Unable to quote %r' % arg
+            print >>file, quoted,
+
+            # For debugging / validation.
+            import ShUtil
+            dequoted = list(ShUtil.ShLexer(quoted).lex())
+            if dequoted != [arg]:
+                raise NotImplementedError,'Unable to quote %r' % arg
+
+        for r in self.redirects:
+            if len(r[0]) == 1:
+                print >>file, "%s '%s'" % (r[0][0], r[1]),
+            else:
+                print >>file, "%s%s '%s'" % (r[0][1], r[0][0], r[1]),
+
+class Pipeline:
+    def __init__(self, commands, negate=False, pipe_err=False):
+        self.commands = commands
+        self.negate = negate
+        self.pipe_err = pipe_err
+
+    def __repr__(self):
+        return 'Pipeline(%r, %r, %r)' % (self.commands, self.negate,
+                                         self.pipe_err)
+
+    def __cmp__(self, other):
+        if not isinstance(other, Pipeline):
+            return -1
+
+        return cmp((self.commands, self.negate, self.pipe_err),
+                   (other.commands, other.negate, self.pipe_err))
+
+    def toShell(self, file, pipefail=False):
+        if pipefail != self.pipe_err:
+            raise ValueError,'Inconsistent "pipefail" attribute!'
+        if self.negate:
+            print >>file, '!',
+        for cmd in self.commands:
+            cmd.toShell(file)
+            if cmd is not self.commands[-1]:
+                print >>file, '|\n ',
+
+class Seq:
+    def __init__(self, lhs, op, rhs):
+        assert op in (';', '&', '||', '&&')
+        self.op = op
+        self.lhs = lhs
+        self.rhs = rhs
+
+    def __repr__(self):
+        return 'Seq(%r, %r, %r)' % (self.lhs, self.op, self.rhs)
+
+    def __cmp__(self, other):
+        if not isinstance(other, Seq):
+            return -1
+
+        return cmp((self.lhs, self.op, self.rhs),
+                   (other.lhs, other.op, other.rhs))
+
+    def toShell(self, file, pipefail=False):
+        self.lhs.toShell(file, pipefail)
+        print >>file, ' %s\n' % self.op
+        self.rhs.toShell(file, pipefail)
diff --git a/src/LLVM/utils/lit/ShUtil.py b/src/LLVM/utils/lit/ShUtil.py
new file mode 100644
index 0000000..c8f9332
--- /dev/null
+++ b/src/LLVM/utils/lit/ShUtil.py
@@ -0,0 +1,346 @@
+import itertools
+
+import Util
+from ShCommands import Command, Pipeline, Seq
+
+class ShLexer:
+    def __init__(self, data, win32Escapes = False):
+        self.data = data
+        self.pos = 0
+        self.end = len(data)
+        self.win32Escapes = win32Escapes
+
+    def eat(self):
+        c = self.data[self.pos]
+        self.pos += 1
+        return c
+
+    def look(self):
+        return self.data[self.pos]
+
+    def maybe_eat(self, c):
+        """
+        maybe_eat(c) - Consume the character c if it is the next character,
+        returning True if a character was consumed. """
+        if self.data[self.pos] == c:
+            self.pos += 1
+            return True
+        return False
+
+    def lex_arg_fast(self, c):
+        # Get the leading whitespace free section.
+        chunk = self.data[self.pos - 1:].split(None, 1)[0]
+        
+        # If it has special characters, the fast path failed.
+        if ('|' in chunk or '&' in chunk or 
+            '<' in chunk or '>' in chunk or
+            "'" in chunk or '"' in chunk or
+            '\\' in chunk):
+            return None
+        
+        self.pos = self.pos - 1 + len(chunk)
+        return chunk
+        
+    def lex_arg_slow(self, c):
+        if c in "'\"":
+            str = self.lex_arg_quoted(c)
+        else:
+            str = c
+        while self.pos != self.end:
+            c = self.look()
+            if c.isspace() or c in "|&":
+                break
+            elif c in '><':
+                # This is an annoying case; we treat '2>' as a single token so
+                # we don't have to track whitespace tokens.
+
+                # If the parse string isn't an integer, do the usual thing.
+                if not str.isdigit():
+                    break
+
+                # Otherwise, lex the operator and convert to a redirection
+                # token.
+                num = int(str)
+                tok = self.lex_one_token()
+                assert isinstance(tok, tuple) and len(tok) == 1
+                return (tok[0], num)                    
+            elif c == '"':
+                self.eat()
+                str += self.lex_arg_quoted('"')
+            elif not self.win32Escapes and c == '\\':
+                # Outside of a string, '\\' escapes everything.
+                self.eat()
+                if self.pos == self.end:
+                    Util.warning("escape at end of quoted argument in: %r" % 
+                                 self.data)
+                    return str
+                str += self.eat()
+            else:
+                str += self.eat()
+        return str
+
+    def lex_arg_quoted(self, delim):
+        str = ''
+        while self.pos != self.end:
+            c = self.eat()
+            if c == delim:
+                return str
+            elif c == '\\' and delim == '"':
+                # Inside a '"' quoted string, '\\' only escapes the quote
+                # character and backslash, otherwise it is preserved.
+                if self.pos == self.end:
+                    Util.warning("escape at end of quoted argument in: %r" % 
+                                 self.data)
+                    return str
+                c = self.eat()
+                if c == '"': # 
+                    str += '"'
+                elif c == '\\':
+                    str += '\\'
+                else:
+                    str += '\\' + c
+            else:
+                str += c
+        Util.warning("missing quote character in %r" % self.data)
+        return str
+    
+    def lex_arg_checked(self, c):
+        pos = self.pos
+        res = self.lex_arg_fast(c)
+        end = self.pos
+
+        self.pos = pos
+        reference = self.lex_arg_slow(c)
+        if res is not None:
+            if res != reference:
+                raise ValueError,"Fast path failure: %r != %r" % (res, reference)
+            if self.pos != end:
+                raise ValueError,"Fast path failure: %r != %r" % (self.pos, end)
+        return reference
+        
+    def lex_arg(self, c):
+        return self.lex_arg_fast(c) or self.lex_arg_slow(c)
+        
+    def lex_one_token(self):
+        """
+        lex_one_token - Lex a single 'sh' token. """
+
+        c = self.eat()
+        if c in ';!':
+            return (c,)
+        if c == '|':
+            if self.maybe_eat('|'):
+                return ('||',)
+            return (c,)
+        if c == '&':
+            if self.maybe_eat('&'):
+                return ('&&',)
+            if self.maybe_eat('>'): 
+                return ('&>',)
+            return (c,)
+        if c == '>':
+            if self.maybe_eat('&'):
+                return ('>&',)
+            if self.maybe_eat('>'):
+                return ('>>',)
+            return (c,)
+        if c == '<':
+            if self.maybe_eat('&'):
+                return ('<&',)
+            if self.maybe_eat('>'):
+                return ('<<',)
+            return (c,)
+
+        return self.lex_arg(c)
+
+    def lex(self):
+        while self.pos != self.end:
+            if self.look().isspace():
+                self.eat()
+            else:
+                yield self.lex_one_token()
+
+###
+ 
+class ShParser:
+    def __init__(self, data, win32Escapes = False):
+        self.data = data
+        self.tokens = ShLexer(data, win32Escapes = win32Escapes).lex()
+    
+    def lex(self):
+        try:
+            return self.tokens.next()
+        except StopIteration:
+            return None
+    
+    def look(self):
+        next = self.lex()
+        if next is not None:
+            self.tokens = itertools.chain([next], self.tokens)
+        return next
+    
+    def parse_command(self):
+        tok = self.lex()
+        if not tok:
+            raise ValueError,"empty command!"
+        if isinstance(tok, tuple):
+            raise ValueError,"syntax error near unexpected token %r" % tok[0]
+        
+        args = [tok]
+        redirects = []
+        while 1:
+            tok = self.look()
+
+            # EOF?
+            if tok is None:
+                break
+
+            # If this is an argument, just add it to the current command.
+            if isinstance(tok, str):
+                args.append(self.lex())
+                continue
+
+            # Otherwise see if it is a terminator.
+            assert isinstance(tok, tuple)
+            if tok[0] in ('|',';','&','||','&&'):
+                break
+            
+            # Otherwise it must be a redirection.
+            op = self.lex()
+            arg = self.lex()
+            if not arg:
+                raise ValueError,"syntax error near token %r" % op[0]
+            redirects.append((op, arg))
+
+        return Command(args, redirects)
+
+    def parse_pipeline(self):
+        negate = False
+        if self.look() == ('!',):
+            self.lex()
+            negate = True
+
+        commands = [self.parse_command()]
+        while self.look() == ('|',):
+            self.lex()
+            commands.append(self.parse_command())
+        return Pipeline(commands, negate)
+            
+    def parse(self):
+        lhs = self.parse_pipeline()
+
+        while self.look():
+            operator = self.lex()
+            assert isinstance(operator, tuple) and len(operator) == 1
+
+            if not self.look():
+                raise ValueError, "missing argument to operator %r" % operator[0]
+            
+            # FIXME: Operator precedence!!
+            lhs = Seq(lhs, operator[0], self.parse_pipeline())
+
+        return lhs
+
+###
+
+import unittest
+
+class TestShLexer(unittest.TestCase):
+    def lex(self, str, *args, **kwargs):
+        return list(ShLexer(str, *args, **kwargs).lex())
+
+    def test_basic(self):
+        self.assertEqual(self.lex('a|b>c&d<e'),
+                         ['a', ('|',), 'b', ('>',), 'c', ('&',), 'd', 
+                          ('<',), 'e'])
+
+    def test_redirection_tokens(self):
+        self.assertEqual(self.lex('a2>c'),
+                         ['a2', ('>',), 'c'])
+        self.assertEqual(self.lex('a 2>c'),
+                         ['a', ('>',2), 'c'])
+        
+    def test_quoting(self):
+        self.assertEqual(self.lex(""" 'a' """),
+                         ['a'])
+        self.assertEqual(self.lex(""" "hello\\"world" """),
+                         ['hello"world'])
+        self.assertEqual(self.lex(""" "hello\\'world" """),
+                         ["hello\\'world"])
+        self.assertEqual(self.lex(""" "hello\\\\world" """),
+                         ["hello\\world"])
+        self.assertEqual(self.lex(""" he"llo wo"rld """),
+                         ["hello world"])
+        self.assertEqual(self.lex(""" a\\ b a\\\\b """),
+                         ["a b", "a\\b"])
+        self.assertEqual(self.lex(""" "" "" """),
+                         ["", ""])
+        self.assertEqual(self.lex(""" a\\ b """, win32Escapes = True),
+                         ['a\\', 'b'])
+
+class TestShParse(unittest.TestCase):
+    def parse(self, str):
+        return ShParser(str).parse()
+
+    def test_basic(self):
+        self.assertEqual(self.parse('echo hello'),
+                         Pipeline([Command(['echo', 'hello'], [])], False))
+        self.assertEqual(self.parse('echo ""'),
+                         Pipeline([Command(['echo', ''], [])], False))
+
+    def test_redirection(self):
+        self.assertEqual(self.parse('echo hello > c'),
+                         Pipeline([Command(['echo', 'hello'], 
+                                           [((('>'),), 'c')])], False))
+        self.assertEqual(self.parse('echo hello > c >> d'),
+                         Pipeline([Command(['echo', 'hello'], [(('>',), 'c'),
+                                                     (('>>',), 'd')])], False))
+        self.assertEqual(self.parse('a 2>&1'),
+                         Pipeline([Command(['a'], [(('>&',2), '1')])], False))
+
+    def test_pipeline(self):
+        self.assertEqual(self.parse('a | b'),
+                         Pipeline([Command(['a'], []),
+                                   Command(['b'], [])],
+                                  False))
+
+        self.assertEqual(self.parse('a | b | c'),
+                         Pipeline([Command(['a'], []),
+                                   Command(['b'], []),
+                                   Command(['c'], [])],
+                                  False))
+
+        self.assertEqual(self.parse('! a'),
+                         Pipeline([Command(['a'], [])],
+                                  True))
+
+    def test_list(self):        
+        self.assertEqual(self.parse('a ; b'),
+                         Seq(Pipeline([Command(['a'], [])], False),
+                             ';',
+                             Pipeline([Command(['b'], [])], False)))
+
+        self.assertEqual(self.parse('a & b'),
+                         Seq(Pipeline([Command(['a'], [])], False),
+                             '&',
+                             Pipeline([Command(['b'], [])], False)))
+
+        self.assertEqual(self.parse('a && b'),
+                         Seq(Pipeline([Command(['a'], [])], False),
+                             '&&',
+                             Pipeline([Command(['b'], [])], False)))
+
+        self.assertEqual(self.parse('a || b'),
+                         Seq(Pipeline([Command(['a'], [])], False),
+                             '||',
+                             Pipeline([Command(['b'], [])], False)))
+
+        self.assertEqual(self.parse('a && b || c'),
+                         Seq(Seq(Pipeline([Command(['a'], [])], False),
+                                 '&&',
+                                 Pipeline([Command(['b'], [])], False)),
+                             '||',
+                             Pipeline([Command(['c'], [])], False)))
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/src/LLVM/utils/lit/ShUtil.py.bak b/src/LLVM/utils/lit/ShUtil.py.bak
new file mode 100644
index 0000000..c4bbb3d
--- /dev/null
+++ b/src/LLVM/utils/lit/ShUtil.py.bak
@@ -0,0 +1,346 @@
+import itertools
+
+import Util
+from ShCommands import Command, Pipeline, Seq
+
+class ShLexer:
+    def __init__(self, data, win32Escapes = False):
+        self.data = data
+        self.pos = 0
+        self.end = len(data)
+        self.win32Escapes = win32Escapes
+
+    def eat(self):
+        c = self.data[self.pos]
+        self.pos += 1
+        return c
+
+    def look(self):
+        return self.data[self.pos]
+
+    def maybe_eat(self, c):
+        """
+        maybe_eat(c) - Consume the character c if it is the next character,
+        returning True if a character was consumed. """
+        if self.data[self.pos] == c:
+            self.pos += 1
+            return True
+        return False
+
+    def lex_arg_fast(self, c):
+        # Get the leading whitespace free section.
+        chunk = self.data[self.pos - 1:].split(None, 1)[0]
+        
+        # If it has special characters, the fast path failed.
+        if ('|' in chunk or '&' in chunk or 
+            '<' in chunk or '>' in chunk or
+            "'" in chunk or '"' in chunk or
+            '\\' in chunk):
+            return None
+        
+        self.pos = self.pos - 1 + len(chunk)
+        return chunk
+        
+    def lex_arg_slow(self, c):
+        if c in "'\"":
+            str = self.lex_arg_quoted(c)
+        else:
+            str = c
+        while self.pos != self.end:
+            c = self.look()
+            if c.isspace() or c in "|&":
+                break
+            elif c in '><':
+                # This is an annoying case; we treat '2>' as a single token so
+                # we don't have to track whitespace tokens.
+
+                # If the parse string isn't an integer, do the usual thing.
+                if not str.isdigit():
+                    break
+
+                # Otherwise, lex the operator and convert to a redirection
+                # token.
+                num = int(str)
+                tok = self.lex_one_token()
+                assert isinstance(tok, tuple) and len(tok) == 1
+                return (tok[0], num)                    
+            elif c == '"':
+                self.eat()
+                str += self.lex_arg_quoted('"')

+            elif not self.win32Escapes and c == '\\':
+                # Outside of a string, '\\' escapes everything.
+                self.eat()
+                if self.pos == self.end:
+                    Util.warning("escape at end of quoted argument in: %r" % 
+                                 self.data)
+                    return str
+                str += self.eat()
+            else:
+                str += self.eat()
+        return str
+
+    def lex_arg_quoted(self, delim):
+        str = ''
+        while self.pos != self.end:
+            c = self.eat()
+            if c == delim:
+                return str
+            elif c == '\\' and delim == '"':
+                # Inside a '"' quoted string, '\\' only escapes the quote
+                # character and backslash, otherwise it is preserved.
+                if self.pos == self.end:
+                    Util.warning("escape at end of quoted argument in: %r" % 
+                                 self.data)
+                    return str
+                c = self.eat()
+                if c == '"': # 
+                    str += '"'
+                elif c == '\\':
+                    str += '\\'
+                else:
+                    str += '\\' + c
+            else:
+                str += c
+        Util.warning("missing quote character in %r" % self.data)
+        return str
+    
+    def lex_arg_checked(self, c):
+        pos = self.pos
+        res = self.lex_arg_fast(c)
+        end = self.pos
+
+        self.pos = pos
+        reference = self.lex_arg_slow(c)
+        if res is not None:
+            if res != reference:
+                raise ValueError,"Fast path failure: %r != %r" % (res, reference)
+            if self.pos != end:
+                raise ValueError,"Fast path failure: %r != %r" % (self.pos, end)
+        return reference
+        
+    def lex_arg(self, c):
+        return self.lex_arg_fast(c) or self.lex_arg_slow(c)
+        
+    def lex_one_token(self):
+        """
+        lex_one_token - Lex a single 'sh' token. """
+
+        c = self.eat()
+        if c in ';!':
+            return (c,)
+        if c == '|':
+            if self.maybe_eat('|'):
+                return ('||',)
+            return (c,)
+        if c == '&':
+            if self.maybe_eat('&'):
+                return ('&&',)
+            if self.maybe_eat('>'): 
+                return ('&>',)
+            return (c,)
+        if c == '>':
+            if self.maybe_eat('&'):
+                return ('>&',)
+            if self.maybe_eat('>'):
+                return ('>>',)
+            return (c,)
+        if c == '<':
+            if self.maybe_eat('&'):
+                return ('<&',)
+            if self.maybe_eat('>'):
+                return ('<<',)
+            return (c,)
+
+        return self.lex_arg(c)
+
+    def lex(self):
+        while self.pos != self.end:
+            if self.look().isspace():
+                self.eat()
+            else:
+                yield self.lex_one_token()
+
+###
+ 
+class ShParser:
+    def __init__(self, data, win32Escapes = False):
+        self.data = data
+        self.tokens = ShLexer(data, win32Escapes = win32Escapes).lex()
+    
+    def lex(self):
+        try:
+            return self.tokens.next()
+        except StopIteration:
+            return None
+    
+    def look(self):
+        next = self.lex()
+        if next is not None:
+            self.tokens = itertools.chain([next], self.tokens)
+        return next
+    
+    def parse_command(self):
+        tok = self.lex()
+        if not tok:
+            raise ValueError,"empty command!"
+        if isinstance(tok, tuple):
+            raise ValueError,"syntax error near unexpected token %r" % tok[0]
+        
+        args = [tok]
+        redirects = []
+        while 1:
+            tok = self.look()
+
+            # EOF?
+            if tok is None:
+                break
+
+            # If this is an argument, just add it to the current command.
+            if isinstance(tok, str):
+                args.append(self.lex())
+                continue
+
+            # Otherwise see if it is a terminator.
+            assert isinstance(tok, tuple)
+            if tok[0] in ('|',';','&','||','&&'):
+                break
+            
+            # Otherwise it must be a redirection.
+            op = self.lex()
+            arg = self.lex()
+            if not arg:
+                raise ValueError,"syntax error near token %r" % op[0]
+            redirects.append((op, arg))
+
+        return Command(args, redirects)
+
+    def parse_pipeline(self):
+        negate = False
+        if self.look() == ('!',):
+            self.lex()
+            negate = True
+
+        commands = [self.parse_command()]
+        while self.look() == ('|',):
+            self.lex()
+            commands.append(self.parse_command())
+        return Pipeline(commands, negate)
+            
+    def parse(self):
+        lhs = self.parse_pipeline()
+
+        while self.look():
+            operator = self.lex()
+            assert isinstance(operator, tuple) and len(operator) == 1
+
+            if not self.look():
+                raise ValueError, "missing argument to operator %r" % operator[0]
+            
+            # FIXME: Operator precedence!!
+            lhs = Seq(lhs, operator[0], self.parse_pipeline())
+
+        return lhs
+
+###
+
+import unittest
+
+class TestShLexer(unittest.TestCase):
+    def lex(self, str, *args, **kwargs):
+        return list(ShLexer(str, *args, **kwargs).lex())
+
+    def test_basic(self):
+        self.assertEqual(self.lex('a|b>c&d<e'),
+                         ['a', ('|',), 'b', ('>',), 'c', ('&',), 'd', 
+                          ('<',), 'e'])
+
+    def test_redirection_tokens(self):
+        self.assertEqual(self.lex('a2>c'),
+                         ['a2', ('>',), 'c'])
+        self.assertEqual(self.lex('a 2>c'),
+                         ['a', ('>',2), 'c'])
+        
+    def test_quoting(self):
+        self.assertEqual(self.lex(""" 'a' """),
+                         ['a'])
+        self.assertEqual(self.lex(""" "hello\\"world" """),
+                         ['hello"world'])
+        self.assertEqual(self.lex(""" "hello\\'world" """),
+                         ["hello\\'world"])
+        self.assertEqual(self.lex(""" "hello\\\\world" """),
+                         ["hello\\world"])
+        self.assertEqual(self.lex(""" he"llo wo"rld """),
+                         ["hello world"])
+        self.assertEqual(self.lex(""" a\\ b a\\\\b """),
+                         ["a b", "a\\b"])
+        self.assertEqual(self.lex(""" "" "" """),
+                         ["", ""])
+        self.assertEqual(self.lex(""" a\\ b """, win32Escapes = True),
+                         ['a\\', 'b'])
+
+class TestShParse(unittest.TestCase):
+    def parse(self, str):
+        return ShParser(str).parse()
+
+    def test_basic(self):
+        self.assertEqual(self.parse('echo hello'),
+                         Pipeline([Command(['echo', 'hello'], [])], False))
+        self.assertEqual(self.parse('echo ""'),
+                         Pipeline([Command(['echo', ''], [])], False))
+
+    def test_redirection(self):
+        self.assertEqual(self.parse('echo hello > c'),
+                         Pipeline([Command(['echo', 'hello'], 
+                                           [((('>'),), 'c')])], False))
+        self.assertEqual(self.parse('echo hello > c >> d'),
+                         Pipeline([Command(['echo', 'hello'], [(('>',), 'c'),
+                                                     (('>>',), 'd')])], False))
+        self.assertEqual(self.parse('a 2>&1'),
+                         Pipeline([Command(['a'], [(('>&',2), '1')])], False))
+
+    def test_pipeline(self):
+        self.assertEqual(self.parse('a | b'),
+                         Pipeline([Command(['a'], []),
+                                   Command(['b'], [])],
+                                  False))
+
+        self.assertEqual(self.parse('a | b | c'),
+                         Pipeline([Command(['a'], []),
+                                   Command(['b'], []),
+                                   Command(['c'], [])],
+                                  False))
+
+        self.assertEqual(self.parse('! a'),
+                         Pipeline([Command(['a'], [])],
+                                  True))
+
+    def test_list(self):        
+        self.assertEqual(self.parse('a ; b'),
+                         Seq(Pipeline([Command(['a'], [])], False),
+                             ';',
+                             Pipeline([Command(['b'], [])], False)))
+
+        self.assertEqual(self.parse('a & b'),
+                         Seq(Pipeline([Command(['a'], [])], False),
+                             '&',
+                             Pipeline([Command(['b'], [])], False)))
+
+        self.assertEqual(self.parse('a && b'),
+                         Seq(Pipeline([Command(['a'], [])], False),
+                             '&&',
+                             Pipeline([Command(['b'], [])], False)))
+
+        self.assertEqual(self.parse('a || b'),
+                         Seq(Pipeline([Command(['a'], [])], False),
+                             '||',
+                             Pipeline([Command(['b'], [])], False)))
+
+        self.assertEqual(self.parse('a && b || c'),
+                         Seq(Seq(Pipeline([Command(['a'], [])], False),
+                                 '&&',
+                                 Pipeline([Command(['b'], [])], False)),
+                             '||',
+                             Pipeline([Command(['c'], [])], False)))
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/src/LLVM/utils/lit/TODO b/src/LLVM/utils/lit/TODO
new file mode 100644
index 0000000..4d00d2c
--- /dev/null
+++ b/src/LLVM/utils/lit/TODO
@@ -0,0 +1,19 @@
+ - Move temp directory name into local test config.
+
+ - Add --show-unsupported, don't show by default?
+
+ - Finish documentation.
+
+ - Optionally use multiprocessing.
+
+ - Support llvmc and ocaml tests.
+
+ - Support valgrind in all configs, and LLVM style valgrind.
+
+ - Provide test suite config for running unit tests.
+
+ - Support a timeout / ulimit.
+
+ - Support "disabling" tests? The advantage of making this distinct from XFAIL
+   is it makes it more obvious that it is a temporary measure (and lit can put
+   in a separate category).
diff --git a/src/LLVM/utils/lit/TclUtil.py b/src/LLVM/utils/lit/TclUtil.py
new file mode 100644
index 0000000..4a3f345
--- /dev/null
+++ b/src/LLVM/utils/lit/TclUtil.py
@@ -0,0 +1,322 @@
+import itertools
+
+from ShCommands import Command, Pipeline
+
+def tcl_preprocess(data):
+    # Tcl has a preprocessing step to replace escaped newlines.
+    i = data.find('\\\n')
+    if i == -1:
+        return data
+
+    # Replace '\\\n' and subsequent whitespace by a single space.
+    n = len(data)
+    str = data[:i]
+    i += 2
+    while i < n and data[i] in ' \t':
+        i += 1
+    return str + ' ' + data[i:]
+
+class TclLexer:
+    """TclLexer - Lex a string into "words", following the Tcl syntax."""
+
+    def __init__(self, data):
+        self.data = tcl_preprocess(data)
+        self.pos = 0
+        self.end = len(self.data)
+
+    def at_end(self):
+        return self.pos == self.end
+
+    def eat(self):
+        c = self.data[self.pos]
+        self.pos += 1
+        return c
+
+    def look(self):
+        return self.data[self.pos]
+
+    def maybe_eat(self, c):
+        """
+        maybe_eat(c) - Consume the character c if it is the next character,
+        returning True if a character was consumed. """
+        if self.data[self.pos] == c:
+            self.pos += 1
+            return True
+        return False
+
+    def escape(self, c):
+        if c == 'a':
+            return '\x07'
+        elif c == 'b':
+            return '\x08'
+        elif c == 'f':
+            return '\x0c'
+        elif c == 'n':
+            return '\n'
+        elif c == 'r':
+            return '\r'
+        elif c == 't':
+            return '\t'
+        elif c == 'v':
+            return '\x0b'
+        elif c in 'uxo':
+            raise ValueError,'Invalid quoted character %r' % c
+        else:
+            return c
+        
+    def lex_braced(self):
+        # Lex until whitespace or end of string, the opening brace has already
+        # been consumed.
+
+        str = ''        
+        while 1:
+            if self.at_end():
+                raise ValueError,"Unterminated '{' quoted word"
+            
+            c = self.eat()
+            if c == '}':
+                break
+            elif c == '{':
+                str += '{' + self.lex_braced() + '}'
+            elif c == '\\' and self.look() in '{}':
+                str += self.eat()
+            else:
+                str += c
+
+        return str
+
+    def lex_quoted(self):
+        str = ''
+
+        while 1:
+            if self.at_end():
+                raise ValueError,"Unterminated '\"' quoted word"
+            
+            c = self.eat()
+            if c == '"':
+                break
+            elif c == '\\':
+                if self.at_end():
+                    raise ValueError,'Missing quoted character'
+
+                str += self.escape(self.eat())
+            else:
+                str += c
+
+        return str
+
+    def lex_unquoted(self, process_all=False):
+        # Lex until whitespace or end of string.
+        str = ''
+        while not self.at_end():
+            if not process_all:
+                if self.look().isspace() or self.look() == ';':
+                    break
+
+            c = self.eat()
+            if c == '\\':
+                if self.at_end():
+                    raise ValueError,'Missing quoted character'
+
+                str += self.escape(self.eat())
+            elif c == '[':
+                raise NotImplementedError, ('Command substitution is '
+                                            'not supported')
+            elif c == '$' and not self.at_end() and (self.look().isalpha() or
+                                                     self.look() == '{'):
+                raise NotImplementedError, ('Variable substitution is '
+                                            'not supported')
+            else:
+                str += c
+
+        return str
+
+    def lex_one_token(self):
+        if self.maybe_eat('"'):
+            return self.lex_quoted()
+        elif self.maybe_eat('{'):
+            # Check for argument substitution.
+            if not self.maybe_eat('*'):
+                return self.lex_braced()
+
+            if not self.maybe_eat('}'):
+                    return '*' + self.lex_braced()
+                
+            if self.at_end() or self.look().isspace():
+                return '*'
+
+            raise NotImplementedError, "Argument substitution is unsupported"
+        else:
+            return self.lex_unquoted()
+
+    def lex(self):
+        while not self.at_end():
+            c = self.look()
+            if c in ' \t':
+                self.eat()
+            elif c in ';\n':
+                self.eat()
+                yield (';',)
+            else:
+                yield self.lex_one_token()
+
+class TclExecCommand:
+    kRedirectPrefixes1 = ('<', '>')
+    kRedirectPrefixes2 = ('<@', '<<', '2>', '>&', '>>', '>@')
+    kRedirectPrefixes3 = ('2>@', '2>>', '>>&', '>&@')
+    kRedirectPrefixes4 = ('2>@1',)
+
+    def __init__(self, args):
+        self.args = iter(args)
+
+    def lex(self):
+        try:
+            return self.args.next()
+        except StopIteration:
+            return None
+
+    def look(self):
+        next = self.lex()
+        if next is not None:
+            self.args = itertools.chain([next], self.args)
+        return next
+
+    def parse_redirect(self, tok, length):
+        if len(tok) == length:
+            arg = self.lex()
+            if arg is None:
+                raise ValueError,'Missing argument to %r redirection' % tok
+        else:
+            tok,arg = tok[:length],tok[length:]
+
+        if tok[0] == '2':
+            op = (tok[1:],2)
+        else:
+            op = (tok,)
+        return (op, arg)
+
+    def parse_pipeline(self):
+        if self.look() is None:
+            raise ValueError,"Expected at least one argument to exec"
+
+        commands = [Command([],[])]
+        while 1:
+            arg = self.lex()
+            if arg is None:
+                break
+            elif arg == '|':
+                commands.append(Command([],[]))
+            elif arg == '|&':
+                # Write this as a redirect of stderr; it must come first because
+                # stdout may have already been redirected.
+                commands[-1].redirects.insert(0, (('>&',2),'1'))
+                commands.append(Command([],[]))
+            elif arg[:4] in TclExecCommand.kRedirectPrefixes4:
+                commands[-1].redirects.append(self.parse_redirect(arg, 4))
+            elif arg[:3] in TclExecCommand.kRedirectPrefixes3:
+                commands[-1].redirects.append(self.parse_redirect(arg, 3))
+            elif arg[:2] in TclExecCommand.kRedirectPrefixes2:
+                commands[-1].redirects.append(self.parse_redirect(arg, 2))
+            elif arg[:1] in TclExecCommand.kRedirectPrefixes1:
+                commands[-1].redirects.append(self.parse_redirect(arg, 1))
+            else:
+                commands[-1].args.append(arg)
+
+        return Pipeline(commands, False, pipe_err=True)
+
+    def parse(self):
+        ignoreStderr = False
+        keepNewline = False
+
+        # Parse arguments.
+        while 1:
+            next = self.look()
+            if not isinstance(next, str) or next[0] != '-':
+                break
+
+            if next == '--':
+                self.lex()
+                break
+            elif next == '-ignorestderr':
+                ignoreStderr = True
+            elif next == '-keepnewline':
+                keepNewline = True
+            else:
+                raise ValueError,"Invalid exec argument %r" % next
+
+        return (ignoreStderr, keepNewline, self.parse_pipeline())
+
+###
+
+import unittest
+
+class TestTclLexer(unittest.TestCase):
+    def lex(self, str, *args, **kwargs):
+        return list(TclLexer(str, *args, **kwargs).lex())
+
+    def test_preprocess(self):
+        self.assertEqual(tcl_preprocess('a b'), 'a b')
+        self.assertEqual(tcl_preprocess('a\\\nb c'), 'a b c')
+
+    def test_unquoted(self):
+        self.assertEqual(self.lex('a b c'),
+                         ['a', 'b', 'c'])
+        self.assertEqual(self.lex(r'a\nb\tc\ '),
+                         ['a\nb\tc '])
+        self.assertEqual(self.lex(r'a \\\$b c $\\'),
+                         ['a', r'\$b', 'c', '$\\'])
+
+    def test_braced(self):
+        self.assertEqual(self.lex('a {b c} {}'),
+                         ['a', 'b c', ''])
+        self.assertEqual(self.lex(r'a {b {c\n}}'),
+                         ['a', 'b {c\\n}'])
+        self.assertEqual(self.lex(r'a {b\{}'),
+                         ['a', 'b{'])
+        self.assertEqual(self.lex(r'{*}'), ['*'])
+        self.assertEqual(self.lex(r'{*} a'), ['*', 'a'])
+        self.assertEqual(self.lex(r'{*} a'), ['*', 'a'])
+        self.assertEqual(self.lex('{a\\\n   b}'),
+                         ['a b'])
+
+    def test_quoted(self):
+        self.assertEqual(self.lex('a "b c"'),
+                         ['a', 'b c'])
+
+    def test_terminators(self):
+        self.assertEqual(self.lex('a\nb'),
+                         ['a', (';',), 'b'])
+        self.assertEqual(self.lex('a;b'),
+                         ['a', (';',), 'b'])
+        self.assertEqual(self.lex('a   ;   b'),
+                         ['a', (';',), 'b'])
+
+class TestTclExecCommand(unittest.TestCase):
+    def parse(self, str):
+        return TclExecCommand(list(TclLexer(str).lex())).parse()
+
+    def test_basic(self):
+        self.assertEqual(self.parse('echo hello'),
+                         (False, False,
+                          Pipeline([Command(['echo', 'hello'], [])],
+                                   False, True)))
+        self.assertEqual(self.parse('echo hello | grep hello'),
+                         (False, False,
+                          Pipeline([Command(['echo', 'hello'], []),
+                                    Command(['grep', 'hello'], [])],
+                                   False, True)))
+
+    def test_redirect(self):
+        self.assertEqual(self.parse('echo hello > a >b >>c 2> d |& e'),
+                         (False, False,
+                          Pipeline([Command(['echo', 'hello'],
+                                            [(('>&',2),'1'),
+                                             (('>',),'a'),
+                                             (('>',),'b'),
+                                             (('>>',),'c'),
+                                             (('>',2),'d')]),
+                                    Command(['e'], [])],
+                                   False, True)))
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/src/LLVM/utils/lit/Test.py b/src/LLVM/utils/lit/Test.py
new file mode 100644
index 0000000..1f6556b
--- /dev/null
+++ b/src/LLVM/utils/lit/Test.py
@@ -0,0 +1,79 @@
+import os
+
+# Test results.
+
+class TestResult:
+    def __init__(self, name, isFailure):
+        self.name = name
+        self.isFailure = isFailure
+
+PASS        = TestResult('PASS', False)
+XFAIL       = TestResult('XFAIL', False)
+FAIL        = TestResult('FAIL', True)
+XPASS       = TestResult('XPASS', True)
+UNRESOLVED  = TestResult('UNRESOLVED', True)
+UNSUPPORTED = TestResult('UNSUPPORTED', False)
+
+# Test classes.
+
+class TestFormat:
+    """TestFormat - Test information provider."""
+
+    def __init__(self, name):
+        self.name = name
+
+class TestSuite:
+    """TestSuite - Information on a group of tests.
+
+    A test suite groups together a set of logically related tests.
+    """
+
+    def __init__(self, name, source_root, exec_root, config):
+        self.name = name
+        self.source_root = source_root
+        self.exec_root = exec_root
+        # The test suite configuration.
+        self.config = config
+
+    def getSourcePath(self, components):
+        return os.path.join(self.source_root, *components)
+
+    def getExecPath(self, components):
+        return os.path.join(self.exec_root, *components)
+
+class Test:
+    """Test - Information on a single test instance."""
+
+    def __init__(self, suite, path_in_suite, config):
+        self.suite = suite
+        self.path_in_suite = path_in_suite
+        self.config = config
+        # The test result code, once complete.
+        self.result = None
+        # Any additional output from the test, once complete.
+        self.output = None
+        # The wall time to execute this test, if timing and once complete.
+        self.elapsed = None
+        # The repeat index of this test, or None.
+        self.index = None
+
+    def copyWithIndex(self, index):
+        import copy
+        res = copy.copy(self)
+        res.index = index
+        return res
+
+    def setResult(self, result, output, elapsed):
+        assert self.result is None, "Test result already set!"
+        self.result = result
+        self.output = output
+        self.elapsed = elapsed
+
+    def getFullName(self):
+        return self.suite.config.name + '::' + '/'.join(self.path_in_suite)
+
+    def getSourcePath(self):
+        return self.suite.getSourcePath(self.path_in_suite)
+
+    def getExecPath(self):
+        return self.suite.getExecPath(self.path_in_suite)
diff --git a/src/LLVM/utils/lit/TestFormats.py b/src/LLVM/utils/lit/TestFormats.py
new file mode 100644
index 0000000..5dfd54a
--- /dev/null
+++ b/src/LLVM/utils/lit/TestFormats.py
@@ -0,0 +1,189 @@
+import os
+
+import Test
+import TestRunner
+import Util
+
+class GoogleTest(object):
+    def __init__(self, test_sub_dir, test_suffix):
+        self.test_sub_dir = str(test_sub_dir)
+        self.test_suffix = str(test_suffix)
+
+    def getGTestTests(self, path, litConfig):
+        """getGTestTests(path) - [name]
+        
+        Return the tests available in gtest executable."""
+
+        try:
+            lines = Util.capture([path, '--gtest_list_tests']).split('\n')
+        except:
+            litConfig.error("unable to discover google-tests in %r" % path)
+            raise StopIteration
+
+        nested_tests = []
+        for ln in lines:
+            if not ln.strip():
+                continue
+
+            prefix = ''
+            index = 0
+            while ln[index*2:index*2+2] == '  ':
+                index += 1
+            while len(nested_tests) > index:
+                nested_tests.pop()
+            
+            ln = ln[index*2:]
+            if ln.endswith('.'):
+                nested_tests.append(ln)
+            else:
+                yield ''.join(nested_tests) + ln
+
+    def getTestsInDirectory(self, testSuite, path_in_suite,
+                            litConfig, localConfig):
+        source_path = testSuite.getSourcePath(path_in_suite)
+        for filename in os.listdir(source_path):
+            # Check for the one subdirectory (build directory) tests will be in.
+            if filename != self.test_sub_dir:
+                continue
+
+            filepath = os.path.join(source_path, filename)
+            for subfilename in os.listdir(filepath):
+                if subfilename.endswith(self.test_suffix):
+                    execpath = os.path.join(filepath, subfilename)
+
+                    # Discover the tests in this executable.
+                    for name in self.getGTestTests(execpath, litConfig):
+                        testPath = path_in_suite + (filename, subfilename, name)
+                        yield Test.Test(testSuite, testPath, localConfig)
+
+    def execute(self, test, litConfig):
+        testPath,testName = os.path.split(test.getSourcePath())
+        while not os.path.exists(testPath):
+            # Handle GTest parametrized and typed tests, whose name includes
+            # some '/'s.
+            testPath, namePrefix = os.path.split(testPath)
+            testName = os.path.join(namePrefix, testName)
+
+        cmd = [testPath, '--gtest_filter=' + testName]
+        out, err, exitCode = TestRunner.executeCommand(cmd)
+            
+        if not exitCode:
+            return Test.PASS,''
+
+        return Test.FAIL, out + err
+
+###
+
+class FileBasedTest(object):
+    def getTestsInDirectory(self, testSuite, path_in_suite,
+                            litConfig, localConfig):
+        source_path = testSuite.getSourcePath(path_in_suite)
+        for filename in os.listdir(source_path):
+            filepath = os.path.join(source_path, filename)
+            if not os.path.isdir(filepath):
+                base,ext = os.path.splitext(filename)
+                if ext in localConfig.suffixes:
+                    yield Test.Test(testSuite, path_in_suite + (filename,),
+                                    localConfig)
+
+class ShTest(FileBasedTest):
+    def __init__(self, execute_external = False):
+        self.execute_external = execute_external
+
+    def execute(self, test, litConfig):
+        return TestRunner.executeShTest(test, litConfig,
+                                        self.execute_external)
+
+class TclTest(FileBasedTest):
+    def execute(self, test, litConfig):
+        return TestRunner.executeTclTest(test, litConfig)
+
+###
+
+import re
+import tempfile
+
+class OneCommandPerFileTest:
+    # FIXME: Refactor into generic test for running some command on a directory
+    # of inputs.
+
+    def __init__(self, command, dir, recursive=False,
+                 pattern=".*", useTempInput=False):
+        if isinstance(command, str):
+            self.command = [command]
+        else:
+            self.command = list(command)
+        self.dir = str(dir)
+        self.recursive = bool(recursive)
+        self.pattern = re.compile(pattern)
+        self.useTempInput = useTempInput
+
+    def getTestsInDirectory(self, testSuite, path_in_suite,
+                            litConfig, localConfig):
+        for dirname,subdirs,filenames in os.walk(self.dir):
+            if not self.recursive:
+                subdirs[:] = []
+
+            subdirs[:] = [d for d in subdirs
+                          if (d != '.svn' and
+                              d not in localConfig.excludes)]
+
+            for filename in filenames:
+                if (not self.pattern.match(filename) or
+                    filename in localConfig.excludes):
+                    continue
+
+                path = os.path.join(dirname,filename)
+                suffix = path[len(self.dir):]
+                if suffix.startswith(os.sep):
+                    suffix = suffix[1:]
+                test = Test.Test(testSuite,
+                                 path_in_suite + tuple(suffix.split(os.sep)),
+                                 localConfig)
+                # FIXME: Hack?
+                test.source_path = path
+                yield test
+
+    def createTempInput(self, tmp, test):
+        abstract
+
+    def execute(self, test, litConfig):
+        if test.config.unsupported:
+            return (Test.UNSUPPORTED, 'Test is unsupported')
+
+        cmd = list(self.command)
+
+        # If using temp input, create a temporary file and hand it to the
+        # subclass.
+        if self.useTempInput:
+            tmp = tempfile.NamedTemporaryFile(suffix='.cpp')
+            self.createTempInput(tmp, test)
+            tmp.flush()
+            cmd.append(tmp.name)
+        else:
+            cmd.append(test.source_path)
+
+        out, err, exitCode = TestRunner.executeCommand(cmd)
+
+        diags = out + err
+        if not exitCode and not diags.strip():
+            return Test.PASS,''
+
+        # Try to include some useful information.
+        report = """Command: %s\n""" % ' '.join(["'%s'" % a
+                                                 for a in cmd])
+        if self.useTempInput:
+            report += """Temporary File: %s\n""" % tmp.name
+            report += "--\n%s--\n""" % open(tmp.name).read()
+        report += """Output:\n--\n%s--""" % diags
+
+        return Test.FAIL, report
+
+class SyntaxCheckTest(OneCommandPerFileTest):
+    def __init__(self, compiler, dir, extra_cxx_args=[], *args, **kwargs):
+        cmd = [compiler, '-x', 'c++', '-fsyntax-only'] + extra_cxx_args
+        OneCommandPerFileTest.__init__(self, cmd, dir,
+                                       useTempInput=1, *args, **kwargs)
+
+    def createTempInput(self, tmp, test):
+        print >>tmp, '#include "%s"' % test.source_path
diff --git a/src/LLVM/utils/lit/TestRunner.py b/src/LLVM/utils/lit/TestRunner.py
new file mode 100644
index 0000000..20fbc6c
--- /dev/null
+++ b/src/LLVM/utils/lit/TestRunner.py
@@ -0,0 +1,517 @@
+import os, signal, subprocess, sys
+import StringIO
+
+import ShUtil
+import Test
+import Util
+
+import platform
+import tempfile
+
+class InternalShellError(Exception):
+    def __init__(self, command, message):
+        self.command = command
+        self.message = message
+
+# Don't use close_fds on Windows.
+kUseCloseFDs = platform.system() != 'Windows'
+
+# Use temporary files to replace /dev/null on Windows.
+kAvoidDevNull = platform.system() == 'Windows'
+
+def executeCommand(command, cwd=None, env=None):
+    p = subprocess.Popen(command, cwd=cwd,
+                         stdin=subprocess.PIPE,
+                         stdout=subprocess.PIPE,
+                         stderr=subprocess.PIPE,
+                         env=env)
+    out,err = p.communicate()
+    exitCode = p.wait()
+
+    # Detect Ctrl-C in subprocess.
+    if exitCode == -signal.SIGINT:
+        raise KeyboardInterrupt
+
+    return out, err, exitCode
+
+def executeShCmd(cmd, cfg, cwd, results):
+    if isinstance(cmd, ShUtil.Seq):
+        if cmd.op == ';':
+            res = executeShCmd(cmd.lhs, cfg, cwd, results)
+            return executeShCmd(cmd.rhs, cfg, cwd, results)
+
+        if cmd.op == '&':
+            raise NotImplementedError,"unsupported test command: '&'"
+
+        if cmd.op == '||':
+            res = executeShCmd(cmd.lhs, cfg, cwd, results)
+            if res != 0:
+                res = executeShCmd(cmd.rhs, cfg, cwd, results)
+            return res
+        if cmd.op == '&&':
+            res = executeShCmd(cmd.lhs, cfg, cwd, results)
+            if res is None:
+                return res
+
+            if res == 0:
+                res = executeShCmd(cmd.rhs, cfg, cwd, results)
+            return res
+
+        raise ValueError,'Unknown shell command: %r' % cmd.op
+
+    assert isinstance(cmd, ShUtil.Pipeline)
+    procs = []
+    input = subprocess.PIPE
+    stderrTempFiles = []
+    # To avoid deadlock, we use a single stderr stream for piped
+    # output. This is null until we have seen some output using
+    # stderr.
+    for i,j in enumerate(cmd.commands):
+        # Apply the redirections, we use (N,) as a sentinal to indicate stdin,
+        # stdout, stderr for N equal to 0, 1, or 2 respectively. Redirects to or
+        # from a file are represented with a list [file, mode, file-object]
+        # where file-object is initially None.
+        redirects = [(0,), (1,), (2,)]
+        for r in j.redirects:
+            if r[0] == ('>',2):
+                redirects[2] = [r[1], 'w', None]
+            elif r[0] == ('>>',2):
+                redirects[2] = [r[1], 'a', None]
+            elif r[0] == ('>&',2) and r[1] in '012':
+                redirects[2] = redirects[int(r[1])]
+            elif r[0] == ('>&',) or r[0] == ('&>',):
+                redirects[1] = redirects[2] = [r[1], 'w', None]
+            elif r[0] == ('>',):
+                redirects[1] = [r[1], 'w', None]
+            elif r[0] == ('>>',):
+                redirects[1] = [r[1], 'a', None]
+            elif r[0] == ('<',):
+                redirects[0] = [r[1], 'r', None]
+            else:
+                raise NotImplementedError,"Unsupported redirect: %r" % (r,)
+
+        # Map from the final redirections to something subprocess can handle.
+        final_redirects = []
+        for index,r in enumerate(redirects):
+            if r == (0,):
+                result = input
+            elif r == (1,):
+                if index == 0:
+                    raise NotImplementedError,"Unsupported redirect for stdin"
+                elif index == 1:
+                    result = subprocess.PIPE
+                else:
+                    result = subprocess.STDOUT
+            elif r == (2,):
+                if index != 2:
+                    raise NotImplementedError,"Unsupported redirect on stdout"
+                result = subprocess.PIPE
+            else:
+                if r[2] is None:
+                    if kAvoidDevNull and r[0] == '/dev/null':
+                        r[2] = tempfile.TemporaryFile(mode=r[1])
+                    else:
+                        r[2] = open(r[0], r[1])
+                    # Workaround a Win32 and/or subprocess bug when appending.
+                    if r[1] == 'a':
+                        r[2].seek(0, 2)
+                result = r[2]
+            final_redirects.append(result)
+
+        stdin, stdout, stderr = final_redirects
+
+        # If stderr wants to come from stdout, but stdout isn't a pipe, then put
+        # stderr on a pipe and treat it as stdout.
+        if (stderr == subprocess.STDOUT and stdout != subprocess.PIPE):
+            stderr = subprocess.PIPE
+            stderrIsStdout = True
+        else:
+            stderrIsStdout = False
+
+            # Don't allow stderr on a PIPE except for the last
+            # process, this could deadlock.
+            #
+            # FIXME: This is slow, but so is deadlock.
+            if stderr == subprocess.PIPE and j != cmd.commands[-1]:
+                stderr = tempfile.TemporaryFile(mode='w+b')
+                stderrTempFiles.append((i, stderr))
+
+        # Resolve the executable path ourselves.
+        args = list(j.args)
+        args[0] = Util.which(args[0], cfg.environment['PATH'])
+        if not args[0]:
+            raise InternalShellError(j, '%r: command not found' % j.args[0])
+
+        procs.append(subprocess.Popen(args, cwd=cwd,
+                                      stdin = stdin,
+                                      stdout = stdout,
+                                      stderr = stderr,
+                                      env = cfg.environment,
+                                      close_fds = kUseCloseFDs))
+
+        # Immediately close stdin for any process taking stdin from us.
+        if stdin == subprocess.PIPE:
+            procs[-1].stdin.close()
+            procs[-1].stdin = None
+
+        # Update the current stdin source.
+        if stdout == subprocess.PIPE:
+            input = procs[-1].stdout
+        elif stderrIsStdout:
+            input = procs[-1].stderr
+        else:
+            input = subprocess.PIPE
+
+    # FIXME: There is probably still deadlock potential here. Yawn.
+    procData = [None] * len(procs)
+    procData[-1] = procs[-1].communicate()
+
+    for i in range(len(procs) - 1):
+        if procs[i].stdout is not None:
+            out = procs[i].stdout.read()
+        else:
+            out = ''
+        if procs[i].stderr is not None:
+            err = procs[i].stderr.read()
+        else:
+            err = ''
+        procData[i] = (out,err)
+        
+    # Read stderr out of the temp files.
+    for i,f in stderrTempFiles:
+        f.seek(0, 0)
+        procData[i] = (procData[i][0], f.read())
+
+    exitCode = None
+    for i,(out,err) in enumerate(procData):
+        res = procs[i].wait()
+        # Detect Ctrl-C in subprocess.
+        if res == -signal.SIGINT:
+            raise KeyboardInterrupt
+
+        results.append((cmd.commands[i], out, err, res))
+        if cmd.pipe_err:
+            # Python treats the exit code as a signed char.
+            if res < 0:
+                exitCode = min(exitCode, res)
+            else:
+                exitCode = max(exitCode, res)
+        else:
+            exitCode = res
+
+    if cmd.negate:
+        exitCode = not exitCode
+
+    return exitCode
+
+def executeScriptInternal(test, litConfig, tmpBase, commands, cwd):
+    ln = ' &&\n'.join(commands)
+    try:
+        cmd = ShUtil.ShParser(ln, litConfig.isWindows).parse()
+    except:
+        return (Test.FAIL, "shell parser error on: %r" % ln)
+
+    results = []
+    try:
+        exitCode = executeShCmd(cmd, test.config, cwd, results)
+    except InternalShellError,e:
+        out = ''
+        err = e.message
+        exitCode = 255
+
+    out = err = ''
+    for i,(cmd, cmd_out,cmd_err,res) in enumerate(results):
+        out += 'Command %d: %s\n' % (i, ' '.join('"%s"' % s for s in cmd.args))
+        out += 'Command %d Result: %r\n' % (i, res)
+        out += 'Command %d Output:\n%s\n\n' % (i, cmd_out)
+        out += 'Command %d Stderr:\n%s\n\n' % (i, cmd_err)
+
+    return out, err, exitCode
+
+def executeTclScriptInternal(test, litConfig, tmpBase, commands, cwd):
+    import TclUtil
+    cmds = []
+    for ln in commands:
+        # Given the unfortunate way LLVM's test are written, the line gets
+        # backslash substitution done twice.
+        ln = TclUtil.TclLexer(ln).lex_unquoted(process_all = True)
+
+        try:
+            tokens = list(TclUtil.TclLexer(ln).lex())
+        except:
+            return (Test.FAIL, "Tcl lexer error on: %r" % ln)
+
+        # Validate there are no control tokens.
+        for t in tokens:
+            if not isinstance(t, str):
+                return (Test.FAIL,
+                        "Invalid test line: %r containing %r" % (ln, t))
+
+        try:
+            cmds.append(TclUtil.TclExecCommand(tokens).parse_pipeline())
+        except:
+            return (Test.FAIL, "Tcl 'exec' parse error on: %r" % ln)
+
+    cmd = cmds[0]
+    for c in cmds[1:]:
+        cmd = ShUtil.Seq(cmd, '&&', c)
+
+    # FIXME: This is lame, we shouldn't need bash. See PR5240.
+    bashPath = litConfig.getBashPath()
+    if litConfig.useTclAsSh and bashPath:
+        script = tmpBase + '.script'
+
+        # Write script file
+        f = open(script,'w')
+        print >>f, 'set -o pipefail'
+        cmd.toShell(f, pipefail = True)
+        f.close()
+
+        if 0:
+            print >>sys.stdout, cmd
+            print >>sys.stdout, open(script).read()
+            print >>sys.stdout
+            return '', '', 0
+
+        command = [litConfig.getBashPath(), script]
+        out,err,exitCode = executeCommand(command, cwd=cwd,
+                                          env=test.config.environment)
+
+        # Tcl commands fail on standard error output.
+        if err:
+            exitCode = 1
+            out = 'Command has output on stderr!\n\n' + out
+
+        return out,err,exitCode
+    else:
+        results = []
+        try:
+            exitCode = executeShCmd(cmd, test.config, cwd, results)
+        except InternalShellError,e:
+            results.append((e.command, '', e.message + '\n', 255))
+            exitCode = 255
+
+    out = err = ''
+
+    # Tcl commands fail on standard error output.
+    if [True for _,_,err,res in results if err]:
+        exitCode = 1
+        out += 'Command has output on stderr!\n\n'
+
+    for i,(cmd, cmd_out, cmd_err, res) in enumerate(results):
+        out += 'Command %d: %s\n' % (i, ' '.join('"%s"' % s for s in cmd.args))
+        out += 'Command %d Result: %r\n' % (i, res)
+        out += 'Command %d Output:\n%s\n\n' % (i, cmd_out)
+        out += 'Command %d Stderr:\n%s\n\n' % (i, cmd_err)
+
+    return out, err, exitCode
+
+def executeScript(test, litConfig, tmpBase, commands, cwd):
+    script = tmpBase + '.script'
+    if litConfig.isWindows:
+        script += '.bat'
+
+    # Write script file
+    f = open(script,'w')
+    if litConfig.isWindows:
+        f.write('\nif %ERRORLEVEL% NEQ 0 EXIT\n'.join(commands))
+    else:
+        f.write(' &&\n'.join(commands))
+    f.write('\n')
+    f.close()
+
+    if litConfig.isWindows:
+        command = ['cmd','/c', script]
+    else:
+        command = ['/bin/sh', script]
+        if litConfig.useValgrind:
+            # FIXME: Running valgrind on sh is overkill. We probably could just
+            # run on clang with no real loss.
+            valgrindArgs = ['valgrind', '-q',
+                            '--tool=memcheck', '--trace-children=yes',
+                            '--error-exitcode=123']
+            valgrindArgs.extend(litConfig.valgrindArgs)
+
+            command = valgrindArgs + command
+
+    return executeCommand(command, cwd=cwd, env=test.config.environment)
+
+def isExpectedFail(xfails, xtargets, target_triple):
+    # Check if any xfail matches this target.
+    for item in xfails:
+        if item == '*' or item in target_triple:
+            break
+    else:
+        return False
+
+    # If so, see if it is expected to pass on this target.
+    #
+    # FIXME: Rename XTARGET to something that makes sense, like XPASS.
+    for item in xtargets:
+        if item == '*' or item in target_triple:
+            return False
+
+    return True
+
+def parseIntegratedTestScript(test):
+    """parseIntegratedTestScript - Scan an LLVM/Clang style integrated test
+    script and extract the lines to 'RUN' as well as 'XFAIL' and 'XTARGET'
+    information. The RUN lines also will have variable substitution performed.
+    """
+
+    # Get the temporary location, this is always relative to the test suite
+    # root, not test source root.
+    #
+    # FIXME: This should not be here?
+    sourcepath = test.getSourcePath()
+    execpath = test.getExecPath()
+    execdir,execbase = os.path.split(execpath)
+    tmpBase = os.path.join(execdir, 'Output', execbase)
+    if test.index is not None:
+        tmpBase += '_%d' % test.index
+
+    # We use #_MARKER_# to hide %% while we do the other substitutions.
+    substitutions = [('%%', '#_MARKER_#')]
+    substitutions.extend(test.config.substitutions)
+    substitutions.extend([('%s', sourcepath),
+                          ('%S', os.path.dirname(sourcepath)),
+                          ('%p', os.path.dirname(sourcepath)),
+                          ('%t', tmpBase + '.tmp'),
+                          # FIXME: Remove this once we kill DejaGNU.
+                          ('%abs_tmp', tmpBase + '.tmp'),
+                          ('#_MARKER_#', '%')])
+
+    # Collect the test lines from the script.
+    script = []
+    xfails = []
+    xtargets = []
+    for ln in open(sourcepath):
+        if 'RUN:' in ln:
+            # Isolate the command to run.
+            index = ln.index('RUN:')
+            ln = ln[index+4:]
+
+            # Trim trailing whitespace.
+            ln = ln.rstrip()
+
+            # Collapse lines with trailing '\\'.
+            if script and script[-1][-1] == '\\':
+                script[-1] = script[-1][:-1] + ln
+            else:
+                script.append(ln)
+        elif 'XFAIL:' in ln:
+            items = ln[ln.index('XFAIL:') + 6:].split(',')
+            xfails.extend([s.strip() for s in items])
+        elif 'XTARGET:' in ln:
+            items = ln[ln.index('XTARGET:') + 8:].split(',')
+            xtargets.extend([s.strip() for s in items])
+        elif 'END.' in ln:
+            # Check for END. lines.
+            if ln[ln.index('END.'):].strip() == 'END.':
+                break
+
+    # Apply substitutions to the script.
+    def processLine(ln):
+        # Apply substitutions
+        for a,b in substitutions:
+            ln = ln.replace(a,b)
+
+        # Strip the trailing newline and any extra whitespace.
+        return ln.strip()
+    script = map(processLine, script)
+
+    # Verify the script contains a run line.
+    if not script:
+        return (Test.UNRESOLVED, "Test has no run line!")
+
+    if script[-1][-1] == '\\':
+        return (Test.UNRESOLVED, "Test has unterminated run lines (with '\\')")
+
+    isXFail = isExpectedFail(xfails, xtargets, test.suite.config.target_triple)
+    return script,isXFail,tmpBase,execdir
+
+def formatTestOutput(status, out, err, exitCode, script):
+    output = StringIO.StringIO()
+    print >>output, "Script:"
+    print >>output, "--"
+    print >>output, '\n'.join(script)
+    print >>output, "--"
+    print >>output, "Exit Code: %r" % exitCode
+    print >>output, "Command Output (stdout):"
+    print >>output, "--"
+    output.write(out)
+    print >>output, "--"
+    print >>output, "Command Output (stderr):"
+    print >>output, "--"
+    output.write(err)
+    print >>output, "--"
+    return (status, output.getvalue())
+
+def executeTclTest(test, litConfig):
+    if test.config.unsupported:
+        return (Test.UNSUPPORTED, 'Test is unsupported')
+
+    res = parseIntegratedTestScript(test)
+    if len(res) == 2:
+        return res
+
+    script, isXFail, tmpBase, execdir = res
+
+    if litConfig.noExecute:
+        return (Test.PASS, '')
+
+    # Create the output directory if it does not already exist.
+    Util.mkdir_p(os.path.dirname(tmpBase))
+
+    res = executeTclScriptInternal(test, litConfig, tmpBase, script, execdir)
+    if len(res) == 2:
+        return res
+
+    out,err,exitCode = res
+    if isXFail:
+        ok = exitCode != 0
+        status = (Test.XPASS, Test.XFAIL)[ok]
+    else:
+        ok = exitCode == 0
+        status = (Test.FAIL, Test.PASS)[ok]
+
+    if ok:
+        return (status,'')
+
+    return formatTestOutput(status, out, err, exitCode, script)
+
+def executeShTest(test, litConfig, useExternalSh):
+    if test.config.unsupported:
+        return (Test.UNSUPPORTED, 'Test is unsupported')
+
+    res = parseIntegratedTestScript(test)
+    if len(res) == 2:
+        return res
+
+    script, isXFail, tmpBase, execdir = res
+
+    if litConfig.noExecute:
+        return (Test.PASS, '')
+
+    # Create the output directory if it does not already exist.
+    Util.mkdir_p(os.path.dirname(tmpBase))
+
+    if useExternalSh:
+        res = executeScript(test, litConfig, tmpBase, script, execdir)
+    else:
+        res = executeScriptInternal(test, litConfig, tmpBase, script, execdir)
+    if len(res) == 2:
+        return res
+
+    out,err,exitCode = res
+    if isXFail:
+        ok = exitCode != 0
+        status = (Test.XPASS, Test.XFAIL)[ok]
+    else:
+        ok = exitCode == 0
+        status = (Test.FAIL, Test.PASS)[ok]
+
+    if ok:
+        return (status,'')
+
+    return formatTestOutput(status, out, err, exitCode, script)
diff --git a/src/LLVM/utils/lit/TestingConfig.py b/src/LLVM/utils/lit/TestingConfig.py
new file mode 100644
index 0000000..1f5067c
--- /dev/null
+++ b/src/LLVM/utils/lit/TestingConfig.py
@@ -0,0 +1,97 @@
+import os
+
+class TestingConfig:
+    """"
+    TestingConfig - Information on the tests inside a suite.
+    """
+
+    @staticmethod
+    def frompath(path, parent, litConfig, mustExist, config = None):
+        if config is None:
+            # Set the environment based on the command line arguments.
+            environment = {
+                'PATH' : os.pathsep.join(litConfig.path +
+                                         [os.environ.get('PATH','')]),
+                'PATHEXT' : os.environ.get('PATHEXT',''),
+                'SYSTEMROOT' : os.environ.get('SYSTEMROOT',''),
+                'LLVM_DISABLE_CRT_DEBUG' : '1',
+                }
+
+            config = TestingConfig(parent,
+                                   name = '<unnamed>',
+                                   suffixes = set(),
+                                   test_format = None,
+                                   environment = environment,
+                                   substitutions = [],
+                                   unsupported = False,
+                                   on_clone = None,
+                                   test_exec_root = None,
+                                   test_source_root = None,
+                                   excludes = [])
+
+        if os.path.exists(path):
+            # FIXME: Improve detection and error reporting of errors in the
+            # config file.
+            f = open(path)
+            cfg_globals = dict(globals())
+            cfg_globals['config'] = config
+            cfg_globals['lit'] = litConfig
+            cfg_globals['__file__'] = path
+            try:
+                exec f in cfg_globals
+            except SystemExit,status:
+                # We allow normal system exit inside a config file to just
+                # return control without error.
+                if status.args:
+                    raise
+            f.close()
+        elif mustExist:
+            litConfig.fatal('unable to load config from %r ' % path)
+
+        config.finish(litConfig)
+        return config
+
+    def __init__(self, parent, name, suffixes, test_format,
+                 environment, substitutions, unsupported, on_clone,
+                 test_exec_root, test_source_root, excludes):
+        self.parent = parent
+        self.name = str(name)
+        self.suffixes = set(suffixes)
+        self.test_format = test_format
+        self.environment = dict(environment)
+        self.substitutions = list(substitutions)
+        self.unsupported = unsupported
+        self.on_clone = on_clone
+        self.test_exec_root = test_exec_root
+        self.test_source_root = test_source_root
+        self.excludes = set(excludes)
+
+    def clone(self, path):
+        # FIXME: Chain implementations?
+        #
+        # FIXME: Allow extra parameters?
+        cfg = TestingConfig(self, self.name, self.suffixes, self.test_format,
+                            self.environment, self.substitutions,
+                            self.unsupported, self.on_clone,
+                            self.test_exec_root, self.test_source_root,
+                            self.excludes)
+        if cfg.on_clone:
+            cfg.on_clone(self, cfg, path)
+        return cfg
+
+    def finish(self, litConfig):
+        """finish() - Finish this config object, after loading is complete."""
+
+        self.name = str(self.name)
+        self.suffixes = set(self.suffixes)
+        self.environment = dict(self.environment)
+        self.substitutions = list(self.substitutions)
+        if self.test_exec_root is not None:
+            # FIXME: This should really only be suite in test suite config
+            # files. Should we distinguish them?
+            self.test_exec_root = str(self.test_exec_root)
+        if self.test_source_root is not None:
+            # FIXME: This should really only be suite in test suite config
+            # files. Should we distinguish them?
+            self.test_source_root = str(self.test_source_root)
+        self.excludes = set(self.excludes)
diff --git a/src/LLVM/utils/lit/Util.py b/src/LLVM/utils/lit/Util.py
new file mode 100644
index 0000000..66c5e46
--- /dev/null
+++ b/src/LLVM/utils/lit/Util.py
@@ -0,0 +1,124 @@
+import os, sys
+
+def detectCPUs():
+    """
+    Detects the number of CPUs on a system. Cribbed from pp.
+    """
+    # Linux, Unix and MacOS:
+    if hasattr(os, "sysconf"):
+        if os.sysconf_names.has_key("SC_NPROCESSORS_ONLN"):
+            # Linux & Unix:
+            ncpus = os.sysconf("SC_NPROCESSORS_ONLN")
+            if isinstance(ncpus, int) and ncpus > 0:
+                return ncpus
+        else: # OSX:
+            return int(os.popen2("sysctl -n hw.ncpu")[1].read())
+    # Windows:
+    if os.environ.has_key("NUMBER_OF_PROCESSORS"):
+        ncpus = int(os.environ["NUMBER_OF_PROCESSORS"])
+        if ncpus > 0:
+            return ncpus
+    return 1 # Default
+
+def mkdir_p(path):
+    """mkdir_p(path) - Make the "path" directory, if it does not exist; this
+    will also make directories for any missing parent directories."""
+    import errno
+
+    if not path or os.path.exists(path):
+        return
+
+    parent = os.path.dirname(path) 
+    if parent != path:
+        mkdir_p(parent)
+
+    try:
+        os.mkdir(path)
+    except OSError,e:
+        # Ignore EEXIST, which may occur during a race condition.
+        if e.errno != errno.EEXIST:
+            raise
+
+def capture(args):
+    import subprocess
+    """capture(command) - Run the given command (or argv list) in a shell and
+    return the standard output."""
+    p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    out,_ = p.communicate()
+    return out
+
+def which(command, paths = None):
+    """which(command, [paths]) - Look up the given command in the paths string
+    (or the PATH environment variable, if unspecified)."""
+
+    if paths is None:
+        paths = os.environ.get('PATH','')
+
+    # Check for absolute match first.
+    if os.path.exists(command):
+        return command
+
+    # Would be nice if Python had a lib function for this.
+    if not paths:
+        paths = os.defpath
+
+    # Get suffixes to search.
+    pathext = os.environ.get('PATHEXT', '').split(os.pathsep)
+
+    # Search the paths...
+    for path in paths.split(os.pathsep):
+        for ext in pathext:
+            p = os.path.join(path, command + ext)
+            if os.path.exists(p):
+                return p
+
+    return None
+
+def printHistogram(items, title = 'Items'):
+    import itertools, math
+
+    items.sort(key = lambda (_,v): v)
+
+    maxValue = max([v for _,v in items])
+
+    # Select first "nice" bar height that produces more than 10 bars.
+    power = int(math.ceil(math.log(maxValue, 10)))
+    for inc in itertools.cycle((5, 2, 2.5, 1)):
+        barH = inc * 10**power
+        N = int(math.ceil(maxValue / barH))
+        if N > 10:
+            break
+        elif inc == 1:
+            power -= 1
+
+    histo = [set() for i in range(N)]
+    for name,v in items:
+        bin = min(int(N * v/maxValue), N-1)
+        histo[bin].add(name)
+
+    barW = 40
+    hr = '-' * (barW + 34)
+    print '\nSlowest %s:' % title
+    print hr
+    for name,value in items[-20:]:
+        print '%.2fs: %s' % (value, name)
+    print '\n%s Times:' % title
+    print hr
+    pDigits = int(math.ceil(math.log(maxValue, 10)))
+    pfDigits = max(0, 3-pDigits)
+    if pfDigits:
+        pDigits += pfDigits + 1
+    cDigits = int(math.ceil(math.log(len(items), 10)))
+    print "[%s] :: [%s] :: [%s]" % ('Range'.center((pDigits+1)*2 + 3),
+                                    'Percentage'.center(barW),
+                                    'Count'.center(cDigits*2 + 1))
+    print hr
+    for i,row in enumerate(histo):
+        pct = float(len(row)) / len(items)
+        w = int(barW * pct)
+        print "[%*.*fs,%*.*fs)" % (pDigits, pfDigits, i*barH,
+                                   pDigits, pfDigits, (i+1)*barH),
+        print ":: [%s%s] :: [%*d/%*d]" % ('*'*w, ' '*(barW-w),
+                                          cDigits, len(row),
+                                          cDigits, len(items))
+
diff --git a/src/LLVM/utils/lit/lit.py b/src/LLVM/utils/lit/lit.py
new file mode 100644
index 0000000..851063b
--- /dev/null
+++ b/src/LLVM/utils/lit/lit.py
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+
+if __name__=='__main__':
+    import lit
+    lit.main()
diff --git a/src/LLVM/utils/lit/lit/ExampleTests/Clang/lit.cfg b/src/LLVM/utils/lit/lit/ExampleTests/Clang/lit.cfg
new file mode 100644
index 0000000..1e1e807
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/ExampleTests/Clang/lit.cfg
@@ -0,0 +1,47 @@
+# -*- Python -*-
+
+# Configuration file for the 'lit' test runner.
+
+# name: The name of this test suite.
+config.name = 'Clang'
+
+# testFormat: The test format to use to interpret tests.
+#
+# For now we require '&&' between commands, until they get globally killed and
+# the test runner updated.
+config.test_format = lit.formats.ShTest(execute_external = True)
+
+# suffixes: A list of file extensions to treat as test files.
+config.suffixes = ['.c', '.cpp', '.m', '.mm']
+
+# target_triple: Used by ShTest and TclTest formats for XFAIL checks.
+config.target_triple = 'foo'
+
+###
+
+# Discover the 'clang' and 'clangcc' to use.
+
+import os
+
+def inferClang(PATH):
+    # Determine which clang to use.
+    clang = os.getenv('CLANG')
+
+    # If the user set clang in the environment, definitely use that and don't
+    # try to validate.
+    if clang:
+        return clang
+
+    # Otherwise look in the path.
+    clang = lit.util.which('clang', PATH)
+
+    if not clang:
+        lit.fatal("couldn't find 'clang' program, try setting "
+                  "CLANG in your environment")
+
+    return clang
+
+clang = inferClang(config.environment['PATH'])
+if not lit.quiet:
+    lit.note('using clang: %r' % clang)
+config.substitutions.append( (' clang ', ' ' + clang + ' ') )
diff --git a/src/LLVM/utils/lit/lit/ExampleTests/LLVM.InTree/test/Bar/dg.exp b/src/LLVM/utils/lit/lit/ExampleTests/LLVM.InTree/test/Bar/dg.exp
new file mode 100644
index 0000000..2bda07a
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/ExampleTests/LLVM.InTree/test/Bar/dg.exp
@@ -0,0 +1,6 @@
+load_lib llvm.exp
+
+if { [llvm_supports_target X86] } {
+  RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll}]]
+}
+
diff --git a/src/LLVM/utils/lit/lit/ExampleTests/LLVM.InTree/test/lit.cfg b/src/LLVM/utils/lit/lit/ExampleTests/LLVM.InTree/test/lit.cfg
new file mode 100644
index 0000000..e7ef037
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/ExampleTests/LLVM.InTree/test/lit.cfg
@@ -0,0 +1,151 @@
+# -*- Python -*-
+
+# Configuration file for the 'lit' test runner.
+
+import os
+
+# name: The name of this test suite.
+config.name = 'LLVM'
+
+# testFormat: The test format to use to interpret tests.
+config.test_format = lit.formats.TclTest()
+
+# suffixes: A list of file extensions to treat as test files, this is actually
+# set by on_clone().
+config.suffixes = []
+
+# test_source_root: The root path where tests are located.
+config.test_source_root = os.path.dirname(__file__)
+
+# test_exec_root: The root path where tests should be run.
+llvm_obj_root = getattr(config, 'llvm_obj_root', None)
+if llvm_obj_root is not None:
+    config.test_exec_root = os.path.join(llvm_obj_root, 'test')
+
+###
+
+import os
+
+# Check that the object root is known.
+if config.test_exec_root is None:
+    # Otherwise, we haven't loaded the site specific configuration (the user is
+    # probably trying to run on a test file directly, and either the site
+    # configuration hasn't been created by the build system, or we are in an
+    # out-of-tree build situation).
+
+    # Try to detect the situation where we are using an out-of-tree build by
+    # looking for 'llvm-config'.
+    #
+    # FIXME: I debated (i.e., wrote and threw away) adding logic to
+    # automagically generate the lit.site.cfg if we are in some kind of fresh
+    # build situation. This means knowing how to invoke the build system
+    # though, and I decided it was too much magic.
+
+    llvm_config = lit.util.which('llvm-config', config.environment['PATH'])
+    if not llvm_config:
+        lit.fatal('No site specific configuration available!')
+
+    # Get the source and object roots.
+    llvm_src_root = lit.util.capture(['llvm-config', '--src-root']).strip()
+    llvm_obj_root = lit.util.capture(['llvm-config', '--obj-root']).strip()
+
+    # Validate that we got a tree which points to here.
+    this_src_root = os.path.dirname(config.test_source_root)
+    if os.path.realpath(llvm_src_root) != os.path.realpath(this_src_root):
+        lit.fatal('No site specific configuration available!')
+
+    # Check that the site specific configuration exists.
+    site_cfg = os.path.join(llvm_obj_root, 'test', 'lit.site.cfg')
+    if not os.path.exists(site_cfg):
+        lit.fatal('No site specific configuration available!')
+
+    # Okay, that worked. Notify the user of the automagic, and reconfigure.
+    lit.note('using out-of-tree build at %r' % llvm_obj_root)
+    lit.load_config(config, site_cfg)
+    raise SystemExit
+
+###
+
+# Load site data from DejaGNU's site.exp.
+import re
+site_exp = {}
+# FIXME: Implement lit.site.cfg.
+for line in open(os.path.join(config.llvm_obj_root, 'test', 'site.exp')):
+    m = re.match('set ([^ ]+) "([^"]*)"', line)
+    if m:
+        site_exp[m.group(1)] = m.group(2)
+
+# Add substitutions.
+for sub in ['prcontext', 'llvmgcc', 'llvmgxx', 'compile_cxx', 'compile_c',
+            'link', 'shlibext', 'ocamlopt', 'llvmdsymutil', 'llvmlibsdir',
+            'bugpoint_topts']:
+    if sub in ('llvmgcc', 'llvmgxx'):
+        config.substitutions.append(('%' + sub,
+                                     site_exp[sub] + ' -emit-llvm -w'))
+    else:
+        config.substitutions.append(('%' + sub, site_exp[sub]))
+
+excludes = []
+
+# Provide target_triple for use in XFAIL and XTARGET.
+config.target_triple = site_exp['target_triplet']
+
+# Provide llvm_supports_target for use in local configs.
+targets = set(site_exp["TARGETS_TO_BUILD"].split())
+def llvm_supports_target(name):
+    return name in targets
+
+langs = set(site_exp['llvmgcc_langs'].split(','))
+def llvm_gcc_supports(name):
+    return name in langs
+
+# Provide on_clone hook for reading 'dg.exp'.
+import os
+simpleLibData = re.compile(r"""load_lib llvm.exp
+
+RunLLVMTests \[lsort \[glob -nocomplain \$srcdir/\$subdir/\*\.(.*)\]\]""",
+                           re.MULTILINE)
+conditionalLibData = re.compile(r"""load_lib llvm.exp
+
+if.*\[ ?(llvm[^ ]*) ([^ ]*) ?\].*{
+ *RunLLVMTests \[lsort \[glob -nocomplain \$srcdir/\$subdir/\*\.(.*)\]\]
+\}""", re.MULTILINE)
+def on_clone(parent, cfg, for_path):
+    def addSuffixes(match):
+        if match[0] == '{' and match[-1] == '}':
+            cfg.suffixes = ['.' + s for s in match[1:-1].split(',')]
+        else:
+            cfg.suffixes = ['.' + match]
+
+    libPath = os.path.join(os.path.dirname(for_path),
+                           'dg.exp')
+    if not os.path.exists(libPath):
+        cfg.unsupported = True
+        return
+
+    # Reset unsupported, in case we inherited it.
+    cfg.unsupported = False
+    lib = open(libPath).read().strip()
+
+    # Check for a simple library.
+    m = simpleLibData.match(lib)
+    if m:
+        addSuffixes(m.group(1))
+        return
+
+    # Check for a conditional test set.
+    m = conditionalLibData.match(lib)
+    if m:
+        funcname,arg,match = m.groups()
+        addSuffixes(match)
+
+        func = globals().get(funcname)
+        if not func:
+            lit.error('unsupported predicate %r' % funcname)
+        elif not func(arg):
+            cfg.unsupported = True
+        return
+    # Otherwise, give up.
+    lit.error('unable to understand %r:\n%s' % (libPath, lib))
+
+config.on_clone = on_clone
diff --git a/src/LLVM/utils/lit/lit/ExampleTests/LLVM.InTree/test/lit.site.cfg b/src/LLVM/utils/lit/lit/ExampleTests/LLVM.InTree/test/lit.site.cfg
new file mode 100644
index 0000000..3bfee54
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/ExampleTests/LLVM.InTree/test/lit.site.cfg
@@ -0,0 +1,10 @@
+# -*- Python -*-
+
+## Autogenerated by Makefile ##
+# Do not edit!
+
+# Preserve some key paths for use by main LLVM test suite config.
+config.llvm_obj_root = os.path.dirname(os.path.dirname(__file__))
+
+# Let the main config do the real work.
+lit.load_config(config, os.path.join(config.llvm_obj_root, 'test/lit.cfg'))
diff --git a/src/LLVM/utils/lit/lit/ExampleTests/LLVM.InTree/test/site.exp b/src/LLVM/utils/lit/lit/ExampleTests/LLVM.InTree/test/site.exp
new file mode 100644
index 0000000..efa839e
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/ExampleTests/LLVM.InTree/test/site.exp
@@ -0,0 +1,28 @@
+## these variables are automatically generated by make ##
+# Do not edit here.  If you wish to override these values
+# edit the last section
+set target_triplet "x86_64-apple-darwin10"
+set TARGETS_TO_BUILD "X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend"
+set llvmgcc_langs "c,c++,objc,obj-c++"
+set prcontext "/usr/bin/tclsh8.4 /Volumes/Data/ddunbar/llvm/test/Scripts/prcontext.tcl"
+set llvmtoolsdir "/Users/ddunbar/llvm.obj.64/Debug/bin"
+set llvmlibsdir "/Users/ddunbar/llvm.obj.64/Debug/lib"
+set srcroot "/Volumes/Data/ddunbar/llvm"
+set objroot "/Volumes/Data/ddunbar/llvm.obj.64"
+set srcdir "/Volumes/Data/ddunbar/llvm/test"
+set objdir "/Volumes/Data/ddunbar/llvm.obj.64/test"
+set gccpath "/usr/bin/gcc -arch x86_64"
+set gxxpath "/usr/bin/g++ -arch x86_64"
+set compile_c " /usr/bin/gcc -arch x86_64 -I/Users/ddunbar/llvm.obj.64/include -I/Users/ddunbar/llvm.obj.64/test -I/Volumes/Data/ddunbar/llvm.obj.64/include -I/Volumes/Data/ddunbar/llvm/include -I/Volumes/Data/ddunbar/llvm/test -D_DEBUG -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -m64 -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -c "
+set compile_cxx " /usr/bin/g++ -arch x86_64 -I/Users/ddunbar/llvm.obj.64/include -I/Users/ddunbar/llvm.obj.64/test -I/Volumes/Data/ddunbar/llvm.obj.64/include -I/Volumes/Data/ddunbar/llvm/include -I/Volumes/Data/ddunbar/llvm/test -D_DEBUG -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -g -fno-exceptions -fno-common -Woverloaded-virtual -m64 -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -c "
+set link " /usr/bin/g++ -arch x86_64 -I/Users/ddunbar/llvm.obj.64/include -I/Users/ddunbar/llvm.obj.64/test -I/Volumes/Data/ddunbar/llvm.obj.64/include -I/Volumes/Data/ddunbar/llvm/include -I/Volumes/Data/ddunbar/llvm/test -D_DEBUG -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -g -fno-exceptions -fno-common -Woverloaded-virtual -m64 -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -g -L/Users/ddunbar/llvm.obj.64/Debug/lib -L/Volumes/Data/ddunbar/llvm.obj.64/Debug/lib "
+set llvmgcc "/Users/ddunbar/llvm-gcc/install/bin/llvm-gcc -m64 "
+set llvmgxx "/Users/ddunbar/llvm-gcc/install/bin/llvm-gcc -m64 "
+set bugpoint_topts "-gcc-tool-args -m64"
+set shlibext ".dylib"
+set ocamlopt "/sw/bin/ocamlopt -cc \"g++ -Wall -D_FILE_OFFSET_BITS=64 -D_REENTRANT\" -I /Users/ddunbar/llvm.obj.64/Debug/lib/ocaml"
+set valgrind ""
+set grep "/usr/bin/grep"
+set gas "/usr/bin/as"
+set llvmdsymutil "dsymutil"
+## All variables above are generated by configure. Do Not Edit ## 
diff --git a/src/LLVM/utils/lit/lit/ExampleTests/LLVM.OutOfTree/obj/test/site.exp b/src/LLVM/utils/lit/lit/ExampleTests/LLVM.OutOfTree/obj/test/site.exp
new file mode 100644
index 0000000..efa839e
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/ExampleTests/LLVM.OutOfTree/obj/test/site.exp
@@ -0,0 +1,28 @@
+## these variables are automatically generated by make ##
+# Do not edit here.  If you wish to override these values
+# edit the last section
+set target_triplet "x86_64-apple-darwin10"
+set TARGETS_TO_BUILD "X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend"
+set llvmgcc_langs "c,c++,objc,obj-c++"
+set prcontext "/usr/bin/tclsh8.4 /Volumes/Data/ddunbar/llvm/test/Scripts/prcontext.tcl"
+set llvmtoolsdir "/Users/ddunbar/llvm.obj.64/Debug/bin"
+set llvmlibsdir "/Users/ddunbar/llvm.obj.64/Debug/lib"
+set srcroot "/Volumes/Data/ddunbar/llvm"
+set objroot "/Volumes/Data/ddunbar/llvm.obj.64"
+set srcdir "/Volumes/Data/ddunbar/llvm/test"
+set objdir "/Volumes/Data/ddunbar/llvm.obj.64/test"
+set gccpath "/usr/bin/gcc -arch x86_64"
+set gxxpath "/usr/bin/g++ -arch x86_64"
+set compile_c " /usr/bin/gcc -arch x86_64 -I/Users/ddunbar/llvm.obj.64/include -I/Users/ddunbar/llvm.obj.64/test -I/Volumes/Data/ddunbar/llvm.obj.64/include -I/Volumes/Data/ddunbar/llvm/include -I/Volumes/Data/ddunbar/llvm/test -D_DEBUG -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -m64 -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -c "
+set compile_cxx " /usr/bin/g++ -arch x86_64 -I/Users/ddunbar/llvm.obj.64/include -I/Users/ddunbar/llvm.obj.64/test -I/Volumes/Data/ddunbar/llvm.obj.64/include -I/Volumes/Data/ddunbar/llvm/include -I/Volumes/Data/ddunbar/llvm/test -D_DEBUG -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -g -fno-exceptions -fno-common -Woverloaded-virtual -m64 -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -c "
+set link " /usr/bin/g++ -arch x86_64 -I/Users/ddunbar/llvm.obj.64/include -I/Users/ddunbar/llvm.obj.64/test -I/Volumes/Data/ddunbar/llvm.obj.64/include -I/Volumes/Data/ddunbar/llvm/include -I/Volumes/Data/ddunbar/llvm/test -D_DEBUG -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -g -fno-exceptions -fno-common -Woverloaded-virtual -m64 -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -g -L/Users/ddunbar/llvm.obj.64/Debug/lib -L/Volumes/Data/ddunbar/llvm.obj.64/Debug/lib "
+set llvmgcc "/Users/ddunbar/llvm-gcc/install/bin/llvm-gcc -m64 "
+set llvmgxx "/Users/ddunbar/llvm-gcc/install/bin/llvm-gcc -m64 "
+set bugpoint_topts "-gcc-tool-args -m64"
+set shlibext ".dylib"
+set ocamlopt "/sw/bin/ocamlopt -cc \"g++ -Wall -D_FILE_OFFSET_BITS=64 -D_REENTRANT\" -I /Users/ddunbar/llvm.obj.64/Debug/lib/ocaml"
+set valgrind ""
+set grep "/usr/bin/grep"
+set gas "/usr/bin/as"
+set llvmdsymutil "dsymutil"
+## All variables above are generated by configure. Do Not Edit ## 
diff --git a/src/LLVM/utils/lit/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/data.txt b/src/LLVM/utils/lit/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/data.txt
new file mode 100644
index 0000000..45b983b
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/data.txt
@@ -0,0 +1 @@
+hi
diff --git a/src/LLVM/utils/lit/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/dg.exp b/src/LLVM/utils/lit/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/dg.exp
new file mode 100644
index 0000000..2bda07a
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/dg.exp
@@ -0,0 +1,6 @@
+load_lib llvm.exp
+
+if { [llvm_supports_target X86] } {
+  RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll}]]
+}
+
diff --git a/src/LLVM/utils/lit/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/pct-S.ll b/src/LLVM/utils/lit/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/pct-S.ll
new file mode 100644
index 0000000..3ff3633
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/pct-S.ll
@@ -0,0 +1 @@
+; RUN: grep "hi" %S/data.txt
diff --git a/src/LLVM/utils/lit/lit/ExampleTests/LLVM.OutOfTree/src/test/lit.cfg b/src/LLVM/utils/lit/lit/ExampleTests/LLVM.OutOfTree/src/test/lit.cfg
new file mode 100644
index 0000000..e7ef037
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/ExampleTests/LLVM.OutOfTree/src/test/lit.cfg
@@ -0,0 +1,151 @@
+# -*- Python -*-
+
+# Configuration file for the 'lit' test runner.
+
+import os
+
+# name: The name of this test suite.
+config.name = 'LLVM'
+
+# testFormat: The test format to use to interpret tests.
+config.test_format = lit.formats.TclTest()
+
+# suffixes: A list of file extensions to treat as test files, this is actually
+# set by on_clone().
+config.suffixes = []
+
+# test_source_root: The root path where tests are located.
+config.test_source_root = os.path.dirname(__file__)
+
+# test_exec_root: The root path where tests should be run.
+llvm_obj_root = getattr(config, 'llvm_obj_root', None)
+if llvm_obj_root is not None:
+    config.test_exec_root = os.path.join(llvm_obj_root, 'test')
+
+###
+
+import os
+
+# Check that the object root is known.
+if config.test_exec_root is None:
+    # Otherwise, we haven't loaded the site specific configuration (the user is
+    # probably trying to run on a test file directly, and either the site
+    # configuration hasn't been created by the build system, or we are in an
+    # out-of-tree build situation).
+
+    # Try to detect the situation where we are using an out-of-tree build by
+    # looking for 'llvm-config'.
+    #
+    # FIXME: I debated (i.e., wrote and threw away) adding logic to
+    # automagically generate the lit.site.cfg if we are in some kind of fresh
+    # build situation. This means knowing how to invoke the build system
+    # though, and I decided it was too much magic.
+
+    llvm_config = lit.util.which('llvm-config', config.environment['PATH'])
+    if not llvm_config:
+        lit.fatal('No site specific configuration available!')
+
+    # Get the source and object roots.
+    llvm_src_root = lit.util.capture(['llvm-config', '--src-root']).strip()
+    llvm_obj_root = lit.util.capture(['llvm-config', '--obj-root']).strip()
+
+    # Validate that we got a tree which points to here.
+    this_src_root = os.path.dirname(config.test_source_root)
+    if os.path.realpath(llvm_src_root) != os.path.realpath(this_src_root):
+        lit.fatal('No site specific configuration available!')
+
+    # Check that the site specific configuration exists.
+    site_cfg = os.path.join(llvm_obj_root, 'test', 'lit.site.cfg')
+    if not os.path.exists(site_cfg):
+        lit.fatal('No site specific configuration available!')
+
+    # Okay, that worked. Notify the user of the automagic, and reconfigure.
+    lit.note('using out-of-tree build at %r' % llvm_obj_root)
+    lit.load_config(config, site_cfg)
+    raise SystemExit
+
+###
+
+# Load site data from DejaGNU's site.exp.
+import re
+site_exp = {}
+# FIXME: Implement lit.site.cfg.
+for line in open(os.path.join(config.llvm_obj_root, 'test', 'site.exp')):
+    m = re.match('set ([^ ]+) "([^"]*)"', line)
+    if m:
+        site_exp[m.group(1)] = m.group(2)
+
+# Add substitutions.
+for sub in ['prcontext', 'llvmgcc', 'llvmgxx', 'compile_cxx', 'compile_c',
+            'link', 'shlibext', 'ocamlopt', 'llvmdsymutil', 'llvmlibsdir',
+            'bugpoint_topts']:
+    if sub in ('llvmgcc', 'llvmgxx'):
+        config.substitutions.append(('%' + sub,
+                                     site_exp[sub] + ' -emit-llvm -w'))
+    else:
+        config.substitutions.append(('%' + sub, site_exp[sub]))
+
+excludes = []
+
+# Provide target_triple for use in XFAIL and XTARGET.
+config.target_triple = site_exp['target_triplet']
+
+# Provide llvm_supports_target for use in local configs.
+targets = set(site_exp["TARGETS_TO_BUILD"].split())
+def llvm_supports_target(name):
+    return name in targets
+
+langs = set(site_exp['llvmgcc_langs'].split(','))
+def llvm_gcc_supports(name):
+    return name in langs
+
+# Provide on_clone hook for reading 'dg.exp'.
+import os
+simpleLibData = re.compile(r"""load_lib llvm.exp
+
+RunLLVMTests \[lsort \[glob -nocomplain \$srcdir/\$subdir/\*\.(.*)\]\]""",
+                           re.MULTILINE)
+conditionalLibData = re.compile(r"""load_lib llvm.exp
+
+if.*\[ ?(llvm[^ ]*) ([^ ]*) ?\].*{
+ *RunLLVMTests \[lsort \[glob -nocomplain \$srcdir/\$subdir/\*\.(.*)\]\]
+\}""", re.MULTILINE)
+def on_clone(parent, cfg, for_path):
+    def addSuffixes(match):
+        if match[0] == '{' and match[-1] == '}':
+            cfg.suffixes = ['.' + s for s in match[1:-1].split(',')]
+        else:
+            cfg.suffixes = ['.' + match]
+
+    libPath = os.path.join(os.path.dirname(for_path),
+                           'dg.exp')
+    if not os.path.exists(libPath):
+        cfg.unsupported = True
+        return
+
+    # Reset unsupported, in case we inherited it.
+    cfg.unsupported = False
+    lib = open(libPath).read().strip()
+
+    # Check for a simple library.
+    m = simpleLibData.match(lib)
+    if m:
+        addSuffixes(m.group(1))
+        return
+
+    # Check for a conditional test set.
+    m = conditionalLibData.match(lib)
+    if m:
+        funcname,arg,match = m.groups()
+        addSuffixes(match)
+
+        func = globals().get(funcname)
+        if not func:
+            lit.error('unsupported predicate %r' % funcname)
+        elif not func(arg):
+            cfg.unsupported = True
+        return
+    # Otherwise, give up.
+    lit.error('unable to understand %r:\n%s' % (libPath, lib))
+
+config.on_clone = on_clone
diff --git a/src/LLVM/utils/lit/lit/ExampleTests/TclTest/stderr-pipe.ll b/src/LLVM/utils/lit/lit/ExampleTests/TclTest/stderr-pipe.ll
new file mode 100644
index 0000000..6c55fe8
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/ExampleTests/TclTest/stderr-pipe.ll
@@ -0,0 +1 @@
+; RUN: gcc -### > /dev/null |& grep {gcc version}
diff --git a/src/LLVM/utils/lit/lit/ExampleTests/fail.c b/src/LLVM/utils/lit/lit/ExampleTests/fail.c
new file mode 100644
index 0000000..84db41a
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/ExampleTests/fail.c
@@ -0,0 +1,2 @@
+// RUN: echo 'I am some stdout'
+// RUN: false
diff --git a/src/LLVM/utils/lit/lit/ExampleTests/lit.cfg b/src/LLVM/utils/lit/lit/ExampleTests/lit.cfg
new file mode 100644
index 0000000..20ee37d
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/ExampleTests/lit.cfg
@@ -0,0 +1,26 @@
+# -*- Python -*-
+
+# Configuration file for the 'lit' test runner.
+
+# name: The name of this test suite.
+config.name = 'Examples'
+
+# suffixes: A list of file extensions to treat as test files.
+config.suffixes = ['.c', '.cpp', '.m', '.mm', '.ll']
+
+# testFormat: The test format to use to interpret tests.
+config.test_format = lit.formats.ShTest()
+
+# test_source_root: The path where tests are located (default is the test suite
+# root).
+config.test_source_root = None
+
+# test_exec_root: The path where tests are located (default is the test suite
+# root).
+config.test_exec_root = None
+
+# target_triple: Used by ShTest and TclTest formats for XFAIL checks.
+config.target_triple = 'foo'
+
+# available_features: Used by ShTest and TclTest formats for REQUIRES checks.
+config.available_features = ['some-feature-name']
diff --git a/src/LLVM/utils/lit/lit/ExampleTests/pass.c b/src/LLVM/utils/lit/lit/ExampleTests/pass.c
new file mode 100644
index 0000000..5c1031c
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/ExampleTests/pass.c
@@ -0,0 +1 @@
+// RUN: true
diff --git a/src/LLVM/utils/lit/lit/ExampleTests/xfail.c b/src/LLVM/utils/lit/lit/ExampleTests/xfail.c
new file mode 100644
index 0000000..b36cd99
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/ExampleTests/xfail.c
@@ -0,0 +1,2 @@
+// RUN: false
+// XFAIL: *
diff --git a/src/LLVM/utils/lit/lit/ExampleTests/xpass.c b/src/LLVM/utils/lit/lit/ExampleTests/xpass.c
new file mode 100644
index 0000000..ad84990
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/ExampleTests/xpass.c
@@ -0,0 +1,2 @@
+// RUN: true
+// XFAIL
diff --git a/src/LLVM/utils/lit/lit/LitConfig.py b/src/LLVM/utils/lit/lit/LitConfig.py
new file mode 100644
index 0000000..ac48591
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/LitConfig.py
@@ -0,0 +1,112 @@
+class LitConfig:
+    """LitConfig - Configuration data for a 'lit' test runner instance, shared
+    across all tests.
+
+    The LitConfig object is also used to communicate with client configuration
+    files, it is always passed in as the global variable 'lit' so that
+    configuration files can access common functionality and internal components
+    easily.
+    """
+
+    # Provide access to built-in formats.
+    import LitFormats as formats
+
+    # Provide access to built-in utility functions.
+    import Util as util
+
+    def __init__(self, progname, path, quiet,
+                 useValgrind, valgrindLeakCheck, valgrindArgs,
+                 useTclAsSh,
+                 noExecute, debug, isWindows,
+                 params):
+        # The name of the test runner.
+        self.progname = progname
+        # The items to add to the PATH environment variable.
+        self.path = list(map(str, path))
+        self.quiet = bool(quiet)
+        self.useValgrind = bool(useValgrind)
+        self.valgrindLeakCheck = bool(valgrindLeakCheck)
+        self.valgrindUserArgs = list(valgrindArgs)
+        self.useTclAsSh = bool(useTclAsSh)
+        self.noExecute = noExecute
+        self.debug = debug
+        self.isWindows = bool(isWindows)
+        self.params = dict(params)
+        self.bashPath = None
+
+        self.numErrors = 0
+        self.numWarnings = 0
+
+        self.valgrindArgs = []
+        self.valgrindTriple = ""
+        if self.useValgrind:
+            self.valgrindTriple = "-vg"
+            self.valgrindArgs = ['valgrind', '-q', '--run-libc-freeres=no',
+                                 '--tool=memcheck', '--trace-children=yes',
+                                 '--error-exitcode=123']
+            if self.valgrindLeakCheck:
+                self.valgrindTriple += "_leak"
+                self.valgrindArgs.append('--leak-check=full')
+            else:
+                # The default is 'summary'.
+                self.valgrindArgs.append('--leak-check=no')
+            self.valgrindArgs.extend(self.valgrindUserArgs)
+
+
+    def load_config(self, config, path):
+        """load_config(config, path) - Load a config object from an alternate
+        path."""
+        from TestingConfig import TestingConfig
+        return TestingConfig.frompath(path, config.parent, self,
+                                      mustExist = True,
+                                      config = config)
+
+    def getBashPath(self):
+        """getBashPath - Get the path to 'bash'"""
+        import os, Util
+
+        if self.bashPath is not None:
+            return self.bashPath
+
+        self.bashPath = Util.which('bash', os.pathsep.join(self.path))
+        if self.bashPath is None:
+            # Check some known paths.
+            for path in ('/bin/bash', '/usr/bin/bash', '/usr/local/bin/bash'):
+                if os.path.exists(path):
+                    self.bashPath = path
+                    break
+
+        if self.bashPath is None:
+            self.warning("Unable to find 'bash', running Tcl tests internally.")
+            self.bashPath = ''
+
+        return self.bashPath
+
+    def _write_message(self, kind, message):
+        import inspect, os, sys
+
+        # Get the file/line where this message was generated.
+        f = inspect.currentframe()
+        # Step out of _write_message, and then out of wrapper.
+        f = f.f_back.f_back
+        file,line,_,_,_ = inspect.getframeinfo(f)
+        location = '%s:%d' % (os.path.basename(file), line)
+
+        print >>sys.stderr, '%s: %s: %s: %s' % (self.progname, location,
+                                                kind, message)
+
+    def note(self, message):
+        self._write_message('note', message)
+
+    def warning(self, message):
+        self._write_message('warning', message)
+        self.numWarnings += 1
+
+    def error(self, message):
+        self._write_message('error', message)
+        self.numErrors += 1
+
+    def fatal(self, message):
+        import sys
+        self._write_message('fatal', message)
+        sys.exit(2)
diff --git a/src/LLVM/utils/lit/lit/LitFormats.py b/src/LLVM/utils/lit/lit/LitFormats.py
new file mode 100644
index 0000000..e86f103
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/LitFormats.py
@@ -0,0 +1,2 @@
+from TestFormats import GoogleTest, ShTest, TclTest
+from TestFormats import SyntaxCheckTest, OneCommandPerFileTest
diff --git a/src/LLVM/utils/lit/lit/LitTestCase.py b/src/LLVM/utils/lit/lit/LitTestCase.py
new file mode 100644
index 0000000..8951185
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/LitTestCase.py
@@ -0,0 +1,30 @@
+import unittest
+import Test
+
+"""
+TestCase adaptor for providing a 'unittest' compatible interface to 'lit' tests.
+"""
+
+class UnresolvedError(RuntimeError):
+    pass
+        
+class LitTestCase(unittest.TestCase):
+    def __init__(self, test, lit_config):
+        unittest.TestCase.__init__(self)
+        self._test = test
+        self._lit_config = lit_config
+
+    def id(self):
+        return self._test.getFullName()
+
+    def shortDescription(self):
+        return self._test.getFullName()
+
+    def runTest(self):
+        tr, output = self._test.config.test_format.execute(
+            self._test, self._lit_config)
+
+        if tr is Test.UNRESOLVED:
+            raise UnresolvedError(output)
+        elif tr.isFailure:
+            self.fail(output)
diff --git a/src/LLVM/utils/lit/lit/ProgressBar.py b/src/LLVM/utils/lit/lit/ProgressBar.py
new file mode 100644
index 0000000..85c95f5
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/ProgressBar.py
@@ -0,0 +1,267 @@
+#!/usr/bin/env python
+
+# Source: http://code.activestate.com/recipes/475116/, with
+# modifications by Daniel Dunbar.
+
+import sys, re, time
+
+class TerminalController:
+    """
+    A class that can be used to portably generate formatted output to
+    a terminal.  
+    
+    `TerminalController` defines a set of instance variables whose
+    values are initialized to the control sequence necessary to
+    perform a given action.  These can be simply included in normal
+    output to the terminal:
+
+        >>> term = TerminalController()
+        >>> print 'This is '+term.GREEN+'green'+term.NORMAL
+
+    Alternatively, the `render()` method can used, which replaces
+    '${action}' with the string required to perform 'action':
+
+        >>> term = TerminalController()
+        >>> print term.render('This is ${GREEN}green${NORMAL}')
+
+    If the terminal doesn't support a given action, then the value of
+    the corresponding instance variable will be set to ''.  As a
+    result, the above code will still work on terminals that do not
+    support color, except that their output will not be colored.
+    Also, this means that you can test whether the terminal supports a
+    given action by simply testing the truth value of the
+    corresponding instance variable:
+
+        >>> term = TerminalController()
+        >>> if term.CLEAR_SCREEN:
+        ...     print 'This terminal supports clearning the screen.'
+
+    Finally, if the width and height of the terminal are known, then
+    they will be stored in the `COLS` and `LINES` attributes.
+    """
+    # Cursor movement:
+    BOL = ''             #: Move the cursor to the beginning of the line
+    UP = ''              #: Move the cursor up one line
+    DOWN = ''            #: Move the cursor down one line
+    LEFT = ''            #: Move the cursor left one char
+    RIGHT = ''           #: Move the cursor right one char
+
+    # Deletion:
+    CLEAR_SCREEN = ''    #: Clear the screen and move to home position
+    CLEAR_EOL = ''       #: Clear to the end of the line.
+    CLEAR_BOL = ''       #: Clear to the beginning of the line.
+    CLEAR_EOS = ''       #: Clear to the end of the screen
+
+    # Output modes:
+    BOLD = ''            #: Turn on bold mode
+    BLINK = ''           #: Turn on blink mode
+    DIM = ''             #: Turn on half-bright mode
+    REVERSE = ''         #: Turn on reverse-video mode
+    NORMAL = ''          #: Turn off all modes
+
+    # Cursor display:
+    HIDE_CURSOR = ''     #: Make the cursor invisible
+    SHOW_CURSOR = ''     #: Make the cursor visible
+
+    # Terminal size:
+    COLS = None          #: Width of the terminal (None for unknown)
+    LINES = None         #: Height of the terminal (None for unknown)
+
+    # Foreground colors:
+    BLACK = BLUE = GREEN = CYAN = RED = MAGENTA = YELLOW = WHITE = ''
+    
+    # Background colors:
+    BG_BLACK = BG_BLUE = BG_GREEN = BG_CYAN = ''
+    BG_RED = BG_MAGENTA = BG_YELLOW = BG_WHITE = ''
+    
+    _STRING_CAPABILITIES = """
+    BOL=cr UP=cuu1 DOWN=cud1 LEFT=cub1 RIGHT=cuf1
+    CLEAR_SCREEN=clear CLEAR_EOL=el CLEAR_BOL=el1 CLEAR_EOS=ed BOLD=bold
+    BLINK=blink DIM=dim REVERSE=rev UNDERLINE=smul NORMAL=sgr0
+    HIDE_CURSOR=cinvis SHOW_CURSOR=cnorm""".split()
+    _COLORS = """BLACK BLUE GREEN CYAN RED MAGENTA YELLOW WHITE""".split()
+    _ANSICOLORS = "BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE".split()
+
+    def __init__(self, term_stream=sys.stdout):
+        """
+        Create a `TerminalController` and initialize its attributes
+        with appropriate values for the current terminal.
+        `term_stream` is the stream that will be used for terminal
+        output; if this stream is not a tty, then the terminal is
+        assumed to be a dumb terminal (i.e., have no capabilities).
+        """
+        # Curses isn't available on all platforms
+        try: import curses
+        except: return
+
+        # If the stream isn't a tty, then assume it has no capabilities.
+        if not term_stream.isatty(): return
+
+        # Check the terminal type.  If we fail, then assume that the
+        # terminal has no capabilities.
+        try: curses.setupterm()
+        except: return
+
+        # Look up numeric capabilities.
+        self.COLS = curses.tigetnum('cols')
+        self.LINES = curses.tigetnum('lines')
+        
+        # Look up string capabilities.
+        for capability in self._STRING_CAPABILITIES:
+            (attrib, cap_name) = capability.split('=')
+            setattr(self, attrib, self._tigetstr(cap_name) or '')
+
+        # Colors
+        set_fg = self._tigetstr('setf')
+        if set_fg:
+            for i,color in zip(range(len(self._COLORS)), self._COLORS):
+                setattr(self, color, curses.tparm(set_fg, i) or '')
+        set_fg_ansi = self._tigetstr('setaf')
+        if set_fg_ansi:
+            for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS):
+                setattr(self, color, curses.tparm(set_fg_ansi, i) or '')
+        set_bg = self._tigetstr('setb')
+        if set_bg:
+            for i,color in zip(range(len(self._COLORS)), self._COLORS):
+                setattr(self, 'BG_'+color, curses.tparm(set_bg, i) or '')
+        set_bg_ansi = self._tigetstr('setab')
+        if set_bg_ansi:
+            for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS):
+                setattr(self, 'BG_'+color, curses.tparm(set_bg_ansi, i) or '')
+
+    def _tigetstr(self, cap_name):
+        # String capabilities can include "delays" of the form "$<2>".
+        # For any modern terminal, we should be able to just ignore
+        # these, so strip them out.
+        import curses
+        cap = curses.tigetstr(cap_name) or ''
+        return re.sub(r'\$<\d+>[/*]?', '', cap)
+
+    def render(self, template):
+        """
+        Replace each $-substitutions in the given template string with
+        the corresponding terminal control string (if it's defined) or
+        '' (if it's not).
+        """
+        return re.sub(r'\$\$|\${\w+}', self._render_sub, template)
+
+    def _render_sub(self, match):
+        s = match.group()
+        if s == '$$': return s
+        else: return getattr(self, s[2:-1])
+
+#######################################################################
+# Example use case: progress bar
+#######################################################################
+
+class SimpleProgressBar:
+    """
+    A simple progress bar which doesn't need any terminal support.
+
+    This prints out a progress bar like:
+      'Header: 0 .. 10.. 20.. ...'
+    """
+
+    def __init__(self, header):
+        self.header = header
+        self.atIndex = None
+
+    def update(self, percent, message):
+        if self.atIndex is None:
+            sys.stdout.write(self.header)
+            self.atIndex = 0
+
+        next = int(percent*50)
+        if next == self.atIndex:
+            return
+
+        for i in range(self.atIndex, next):
+            idx = i % 5
+            if idx == 0:
+                sys.stdout.write('%-2d' % (i*2))
+            elif idx == 1:
+                pass # Skip second char
+            elif idx < 4:
+                sys.stdout.write('.')
+            else:
+                sys.stdout.write(' ')
+        sys.stdout.flush()
+        self.atIndex = next
+
+    def clear(self):
+        if self.atIndex is not None:
+            sys.stdout.write('\n')
+            sys.stdout.flush()
+            self.atIndex = None
+
+class ProgressBar:
+    """
+    A 3-line progress bar, which looks like::
+    
+                                Header
+        20% [===========----------------------------------]
+                           progress message
+
+    The progress bar is colored, if the terminal supports color
+    output; and adjusts to the width of the terminal.
+    """
+    BAR = '%s${GREEN}[${BOLD}%s%s${NORMAL}${GREEN}]${NORMAL}%s\n'
+    HEADER = '${BOLD}${CYAN}%s${NORMAL}\n\n'
+        
+    def __init__(self, term, header, useETA=True):
+        self.term = term
+        if not (self.term.CLEAR_EOL and self.term.UP and self.term.BOL):
+            raise ValueError("Terminal isn't capable enough -- you "
+                             "should use a simpler progress dispaly.")
+        self.width = self.term.COLS or 75
+        self.bar = term.render(self.BAR)
+        self.header = self.term.render(self.HEADER % header.center(self.width))
+        self.cleared = 1 #: true if we haven't drawn the bar yet.
+        self.useETA = useETA
+        if self.useETA:
+            self.startTime = time.time()
+        self.update(0, '')
+
+    def update(self, percent, message):
+        if self.cleared:
+            sys.stdout.write(self.header)
+            self.cleared = 0
+        prefix = '%3d%% ' % (percent*100,)
+        suffix = ''
+        if self.useETA:
+            elapsed = time.time() - self.startTime
+            if percent > .0001 and elapsed > 1:
+                total = elapsed / percent
+                eta = int(total - elapsed)
+                h = eta//3600.
+                m = (eta//60) % 60
+                s = eta % 60
+                suffix = ' ETA: %02d:%02d:%02d'%(h,m,s)
+        barWidth = self.width - len(prefix) - len(suffix) - 2
+        n = int(barWidth*percent)
+        if len(message) < self.width:
+            message = message + ' '*(self.width - len(message))
+        else:
+            message = '... ' + message[-(self.width-4):]
+        sys.stdout.write(
+            self.term.BOL + self.term.UP + self.term.CLEAR_EOL +
+            (self.bar % (prefix, '='*n, '-'*(barWidth-n), suffix)) +
+            self.term.CLEAR_EOL + message)
+
+    def clear(self):
+        if not self.cleared:
+            sys.stdout.write(self.term.BOL + self.term.CLEAR_EOL +
+                             self.term.UP + self.term.CLEAR_EOL +
+                             self.term.UP + self.term.CLEAR_EOL)
+            self.cleared = 1
+
+def test():
+    import time
+    tc = TerminalController()
+    p = ProgressBar(tc, 'Tests')
+    for i in range(101):
+        p.update(i/100., str(i))        
+        time.sleep(.3)
+
+if __name__=='__main__':
+    test()
diff --git a/src/LLVM/utils/lit/lit/ShCommands.py b/src/LLVM/utils/lit/lit/ShCommands.py
new file mode 100644
index 0000000..4550437
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/ShCommands.py
@@ -0,0 +1,85 @@
+class Command:
+    def __init__(self, args, redirects):
+        self.args = list(args)
+        self.redirects = list(redirects)
+
+    def __repr__(self):
+        return 'Command(%r, %r)' % (self.args, self.redirects)
+
+    def __cmp__(self, other):
+        if not isinstance(other, Command):
+            return -1
+
+        return cmp((self.args, self.redirects),
+                   (other.args, other.redirects))
+
+    def toShell(self, file):
+        for arg in self.args:
+            if "'" not in arg:
+                quoted = "'%s'" % arg
+            elif '"' not in arg and '$' not in arg:
+                quoted = '"%s"' % arg
+            else:
+                raise NotImplementedError,'Unable to quote %r' % arg
+            print >>file, quoted,
+
+            # For debugging / validation.
+            import ShUtil
+            dequoted = list(ShUtil.ShLexer(quoted).lex())
+            if dequoted != [arg]:
+                raise NotImplementedError,'Unable to quote %r' % arg
+
+        for r in self.redirects:
+            if len(r[0]) == 1:
+                print >>file, "%s '%s'" % (r[0][0], r[1]),
+            else:
+                print >>file, "%s%s '%s'" % (r[0][1], r[0][0], r[1]),
+
+class Pipeline:
+    def __init__(self, commands, negate=False, pipe_err=False):
+        self.commands = commands
+        self.negate = negate
+        self.pipe_err = pipe_err
+
+    def __repr__(self):
+        return 'Pipeline(%r, %r, %r)' % (self.commands, self.negate,
+                                         self.pipe_err)
+
+    def __cmp__(self, other):
+        if not isinstance(other, Pipeline):
+            return -1
+
+        return cmp((self.commands, self.negate, self.pipe_err),
+                   (other.commands, other.negate, self.pipe_err))
+
+    def toShell(self, file, pipefail=False):
+        if pipefail != self.pipe_err:
+            raise ValueError,'Inconsistent "pipefail" attribute!'
+        if self.negate:
+            print >>file, '!',
+        for cmd in self.commands:
+            cmd.toShell(file)
+            if cmd is not self.commands[-1]:
+                print >>file, '|\n ',
+
+class Seq:
+    def __init__(self, lhs, op, rhs):
+        assert op in (';', '&', '||', '&&')
+        self.op = op
+        self.lhs = lhs
+        self.rhs = rhs
+
+    def __repr__(self):
+        return 'Seq(%r, %r, %r)' % (self.lhs, self.op, self.rhs)
+
+    def __cmp__(self, other):
+        if not isinstance(other, Seq):
+            return -1
+
+        return cmp((self.lhs, self.op, self.rhs),
+                   (other.lhs, other.op, other.rhs))
+
+    def toShell(self, file, pipefail=False):
+        self.lhs.toShell(file, pipefail)
+        print >>file, ' %s\n' % self.op
+        self.rhs.toShell(file, pipefail)
diff --git a/src/LLVM/utils/lit/lit/ShUtil.py b/src/LLVM/utils/lit/lit/ShUtil.py
new file mode 100644
index 0000000..dda622a
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/ShUtil.py
@@ -0,0 +1,353 @@
+import itertools
+
+import Util
+from ShCommands import Command, Pipeline, Seq
+
+class ShLexer:
+    def __init__(self, data, win32Escapes = False):
+        self.data = data
+        self.pos = 0
+        self.end = len(data)
+        self.win32Escapes = win32Escapes
+
+    def eat(self):
+        c = self.data[self.pos]
+        self.pos += 1
+        return c
+
+    def look(self):
+        return self.data[self.pos]
+
+    def maybe_eat(self, c):
+        """
+        maybe_eat(c) - Consume the character c if it is the next character,
+        returning True if a character was consumed. """
+        if self.data[self.pos] == c:
+            self.pos += 1
+            return True
+        return False
+
+    def lex_arg_fast(self, c):
+        # Get the leading whitespace free section.
+        chunk = self.data[self.pos - 1:].split(None, 1)[0]
+        
+        # If it has special characters, the fast path failed.
+        if ('|' in chunk or '&' in chunk or 
+            '<' in chunk or '>' in chunk or
+            "'" in chunk or '"' in chunk or
+            '\\' in chunk):
+            return None
+        
+        self.pos = self.pos - 1 + len(chunk)
+        return chunk
+        
+    def lex_arg_slow(self, c):
+        if c in "'\"":
+            str = self.lex_arg_quoted(c)
+        else:
+            str = c
+        while self.pos != self.end:
+            c = self.look()
+            if c.isspace() or c in "|&":
+                break
+            elif c in '><':
+                # This is an annoying case; we treat '2>' as a single token so
+                # we don't have to track whitespace tokens.
+
+                # If the parse string isn't an integer, do the usual thing.
+                if not str.isdigit():
+                    break
+
+                # Otherwise, lex the operator and convert to a redirection
+                # token.
+                num = int(str)
+                tok = self.lex_one_token()
+                assert isinstance(tok, tuple) and len(tok) == 1
+                return (tok[0], num)                    
+            elif c == '"':
+                self.eat()
+                str += self.lex_arg_quoted('"')
+            elif c == "'":
+                self.eat()
+                str += self.lex_arg_quoted("'")
+            elif not self.win32Escapes and c == '\\':
+                # Outside of a string, '\\' escapes everything.
+                self.eat()
+                if self.pos == self.end:
+                    Util.warning("escape at end of quoted argument in: %r" % 
+                                 self.data)
+                    return str
+                str += self.eat()
+            else:
+                str += self.eat()
+        return str
+
+    def lex_arg_quoted(self, delim):
+        str = ''
+        while self.pos != self.end:
+            c = self.eat()
+            if c == delim:
+                return str
+            elif c == '\\' and delim == '"':
+                # Inside a '"' quoted string, '\\' only escapes the quote
+                # character and backslash, otherwise it is preserved.
+                if self.pos == self.end:
+                    Util.warning("escape at end of quoted argument in: %r" % 
+                                 self.data)
+                    return str
+                c = self.eat()
+                if c == '"': # 
+                    str += '"'
+                elif c == '\\':
+                    str += '\\'
+                else:
+                    str += '\\' + c
+            else:
+                str += c
+        Util.warning("missing quote character in %r" % self.data)
+        return str
+    
+    def lex_arg_checked(self, c):
+        pos = self.pos
+        res = self.lex_arg_fast(c)
+        end = self.pos
+
+        self.pos = pos
+        reference = self.lex_arg_slow(c)
+        if res is not None:
+            if res != reference:
+                raise ValueError,"Fast path failure: %r != %r" % (res, reference)
+            if self.pos != end:
+                raise ValueError,"Fast path failure: %r != %r" % (self.pos, end)
+        return reference
+        
+    def lex_arg(self, c):
+        return self.lex_arg_fast(c) or self.lex_arg_slow(c)
+        
+    def lex_one_token(self):
+        """
+        lex_one_token - Lex a single 'sh' token. """
+
+        c = self.eat()
+        if c in ';!':
+            return (c,)
+        if c == '|':
+            if self.maybe_eat('|'):
+                return ('||',)
+            return (c,)
+        if c == '&':
+            if self.maybe_eat('&'):
+                return ('&&',)
+            if self.maybe_eat('>'): 
+                return ('&>',)
+            return (c,)
+        if c == '>':
+            if self.maybe_eat('&'):
+                return ('>&',)
+            if self.maybe_eat('>'):
+                return ('>>',)
+            return (c,)
+        if c == '<':
+            if self.maybe_eat('&'):
+                return ('<&',)
+            if self.maybe_eat('>'):
+                return ('<<',)
+            return (c,)
+
+        return self.lex_arg(c)
+
+    def lex(self):
+        while self.pos != self.end:
+            if self.look().isspace():
+                self.eat()
+            else:
+                yield self.lex_one_token()
+
+###
+ 
+class ShParser:
+    def __init__(self, data, win32Escapes = False):
+        self.data = data
+        self.tokens = ShLexer(data, win32Escapes = win32Escapes).lex()
+    
+    def lex(self):
+        try:
+            return self.tokens.next()
+        except StopIteration:
+            return None
+    
+    def look(self):
+        next = self.lex()
+        if next is not None:
+            self.tokens = itertools.chain([next], self.tokens)
+        return next
+    
+    def parse_command(self):
+        tok = self.lex()
+        if not tok:
+            raise ValueError,"empty command!"
+        if isinstance(tok, tuple):
+            raise ValueError,"syntax error near unexpected token %r" % tok[0]
+        
+        args = [tok]
+        redirects = []
+        while 1:
+            tok = self.look()
+
+            # EOF?
+            if tok is None:
+                break
+
+            # If this is an argument, just add it to the current command.
+            if isinstance(tok, str):
+                args.append(self.lex())
+                continue
+
+            # Otherwise see if it is a terminator.
+            assert isinstance(tok, tuple)
+            if tok[0] in ('|',';','&','||','&&'):
+                break
+            
+            # Otherwise it must be a redirection.
+            op = self.lex()
+            arg = self.lex()
+            if not arg:
+                raise ValueError,"syntax error near token %r" % op[0]
+            redirects.append((op, arg))
+
+        return Command(args, redirects)
+
+    def parse_pipeline(self):
+        negate = False
+        if self.look() == ('!',):
+            self.lex()
+            negate = True
+
+        commands = [self.parse_command()]
+        while self.look() == ('|',):
+            self.lex()
+            commands.append(self.parse_command())
+        return Pipeline(commands, negate)
+            
+    def parse(self):
+        lhs = self.parse_pipeline()
+
+        while self.look():
+            operator = self.lex()
+            assert isinstance(operator, tuple) and len(operator) == 1
+
+            if not self.look():
+                raise ValueError, "missing argument to operator %r" % operator[0]
+            
+            # FIXME: Operator precedence!!
+            lhs = Seq(lhs, operator[0], self.parse_pipeline())
+
+        return lhs
+
+###
+
+import unittest
+
+class TestShLexer(unittest.TestCase):
+    def lex(self, str, *args, **kwargs):
+        return list(ShLexer(str, *args, **kwargs).lex())
+
+    def test_basic(self):
+        self.assertEqual(self.lex('a|b>c&d<e'),
+                         ['a', ('|',), 'b', ('>',), 'c', ('&',), 'd', 
+                          ('<',), 'e'])
+
+    def test_redirection_tokens(self):
+        self.assertEqual(self.lex('a2>c'),
+                         ['a2', ('>',), 'c'])
+        self.assertEqual(self.lex('a 2>c'),
+                         ['a', ('>',2), 'c'])
+        
+    def test_quoting(self):
+        self.assertEqual(self.lex(""" 'a' """),
+                         ['a'])
+        self.assertEqual(self.lex(""" "hello\\"world" """),
+                         ['hello"world'])
+        self.assertEqual(self.lex(""" "hello\\'world" """),
+                         ["hello\\'world"])
+        self.assertEqual(self.lex(""" "hello\\\\world" """),
+                         ["hello\\world"])
+        self.assertEqual(self.lex(""" he"llo wo"rld """),
+                         ["hello world"])
+        self.assertEqual(self.lex(""" a\\ b a\\\\b """),
+                         ["a b", "a\\b"])
+        self.assertEqual(self.lex(""" "" "" """),
+                         ["", ""])
+        self.assertEqual(self.lex(""" a\\ b """, win32Escapes = True),
+                         ['a\\', 'b'])
+
+class TestShParse(unittest.TestCase):
+    def parse(self, str):
+        return ShParser(str).parse()
+
+    def test_basic(self):
+        self.assertEqual(self.parse('echo hello'),
+                         Pipeline([Command(['echo', 'hello'], [])], False))
+        self.assertEqual(self.parse('echo ""'),
+                         Pipeline([Command(['echo', ''], [])], False))
+        self.assertEqual(self.parse("""echo -DFOO='a'"""),
+                         Pipeline([Command(['echo', '-DFOO=a'], [])], False))
+        self.assertEqual(self.parse('echo -DFOO="a"'),
+                         Pipeline([Command(['echo', '-DFOO=a'], [])], False))
+
+    def test_redirection(self):
+        self.assertEqual(self.parse('echo hello > c'),
+                         Pipeline([Command(['echo', 'hello'], 
+                                           [((('>'),), 'c')])], False))
+        self.assertEqual(self.parse('echo hello > c >> d'),
+                         Pipeline([Command(['echo', 'hello'], [(('>',), 'c'),
+                                                     (('>>',), 'd')])], False))
+        self.assertEqual(self.parse('a 2>&1'),
+                         Pipeline([Command(['a'], [(('>&',2), '1')])], False))
+
+    def test_pipeline(self):
+        self.assertEqual(self.parse('a | b'),
+                         Pipeline([Command(['a'], []),
+                                   Command(['b'], [])],
+                                  False))
+
+        self.assertEqual(self.parse('a | b | c'),
+                         Pipeline([Command(['a'], []),
+                                   Command(['b'], []),
+                                   Command(['c'], [])],
+                                  False))
+
+        self.assertEqual(self.parse('! a'),
+                         Pipeline([Command(['a'], [])],
+                                  True))
+
+    def test_list(self):        
+        self.assertEqual(self.parse('a ; b'),
+                         Seq(Pipeline([Command(['a'], [])], False),
+                             ';',
+                             Pipeline([Command(['b'], [])], False)))
+
+        self.assertEqual(self.parse('a & b'),
+                         Seq(Pipeline([Command(['a'], [])], False),
+                             '&',
+                             Pipeline([Command(['b'], [])], False)))
+
+        self.assertEqual(self.parse('a && b'),
+                         Seq(Pipeline([Command(['a'], [])], False),
+                             '&&',
+                             Pipeline([Command(['b'], [])], False)))
+
+        self.assertEqual(self.parse('a || b'),
+                         Seq(Pipeline([Command(['a'], [])], False),
+                             '||',
+                             Pipeline([Command(['b'], [])], False)))
+
+        self.assertEqual(self.parse('a && b || c'),
+                         Seq(Seq(Pipeline([Command(['a'], [])], False),
+                                 '&&',
+                                 Pipeline([Command(['b'], [])], False)),
+                             '||',
+                             Pipeline([Command(['c'], [])], False)))
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/src/LLVM/utils/lit/lit/TclUtil.py b/src/LLVM/utils/lit/lit/TclUtil.py
new file mode 100644
index 0000000..4a3f345
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/TclUtil.py
@@ -0,0 +1,322 @@
+import itertools
+
+from ShCommands import Command, Pipeline
+
+def tcl_preprocess(data):
+    # Tcl has a preprocessing step to replace escaped newlines.
+    i = data.find('\\\n')
+    if i == -1:
+        return data
+
+    # Replace '\\\n' and subsequent whitespace by a single space.
+    n = len(data)
+    str = data[:i]
+    i += 2
+    while i < n and data[i] in ' \t':
+        i += 1
+    return str + ' ' + data[i:]
+
+class TclLexer:
+    """TclLexer - Lex a string into "words", following the Tcl syntax."""
+
+    def __init__(self, data):
+        self.data = tcl_preprocess(data)
+        self.pos = 0
+        self.end = len(self.data)
+
+    def at_end(self):
+        return self.pos == self.end
+
+    def eat(self):
+        c = self.data[self.pos]
+        self.pos += 1
+        return c
+
+    def look(self):
+        return self.data[self.pos]
+
+    def maybe_eat(self, c):
+        """
+        maybe_eat(c) - Consume the character c if it is the next character,
+        returning True if a character was consumed. """
+        if self.data[self.pos] == c:
+            self.pos += 1
+            return True
+        return False
+
+    def escape(self, c):
+        if c == 'a':
+            return '\x07'
+        elif c == 'b':
+            return '\x08'
+        elif c == 'f':
+            return '\x0c'
+        elif c == 'n':
+            return '\n'
+        elif c == 'r':
+            return '\r'
+        elif c == 't':
+            return '\t'
+        elif c == 'v':
+            return '\x0b'
+        elif c in 'uxo':
+            raise ValueError,'Invalid quoted character %r' % c
+        else:
+            return c
+        
+    def lex_braced(self):
+        # Lex until whitespace or end of string, the opening brace has already
+        # been consumed.
+
+        str = ''        
+        while 1:
+            if self.at_end():
+                raise ValueError,"Unterminated '{' quoted word"
+            
+            c = self.eat()
+            if c == '}':
+                break
+            elif c == '{':
+                str += '{' + self.lex_braced() + '}'
+            elif c == '\\' and self.look() in '{}':
+                str += self.eat()
+            else:
+                str += c
+
+        return str
+
+    def lex_quoted(self):
+        str = ''
+
+        while 1:
+            if self.at_end():
+                raise ValueError,"Unterminated '\"' quoted word"
+            
+            c = self.eat()
+            if c == '"':
+                break
+            elif c == '\\':
+                if self.at_end():
+                    raise ValueError,'Missing quoted character'
+
+                str += self.escape(self.eat())
+            else:
+                str += c
+
+        return str
+
+    def lex_unquoted(self, process_all=False):
+        # Lex until whitespace or end of string.
+        str = ''
+        while not self.at_end():
+            if not process_all:
+                if self.look().isspace() or self.look() == ';':
+                    break
+
+            c = self.eat()
+            if c == '\\':
+                if self.at_end():
+                    raise ValueError,'Missing quoted character'
+
+                str += self.escape(self.eat())
+            elif c == '[':
+                raise NotImplementedError, ('Command substitution is '
+                                            'not supported')
+            elif c == '$' and not self.at_end() and (self.look().isalpha() or
+                                                     self.look() == '{'):
+                raise NotImplementedError, ('Variable substitution is '
+                                            'not supported')
+            else:
+                str += c
+
+        return str
+
+    def lex_one_token(self):
+        if self.maybe_eat('"'):
+            return self.lex_quoted()
+        elif self.maybe_eat('{'):
+            # Check for argument substitution.
+            if not self.maybe_eat('*'):
+                return self.lex_braced()
+
+            if not self.maybe_eat('}'):
+                    return '*' + self.lex_braced()
+                
+            if self.at_end() or self.look().isspace():
+                return '*'
+
+            raise NotImplementedError, "Argument substitution is unsupported"
+        else:
+            return self.lex_unquoted()
+
+    def lex(self):
+        while not self.at_end():
+            c = self.look()
+            if c in ' \t':
+                self.eat()
+            elif c in ';\n':
+                self.eat()
+                yield (';',)
+            else:
+                yield self.lex_one_token()
+
+class TclExecCommand:
+    kRedirectPrefixes1 = ('<', '>')
+    kRedirectPrefixes2 = ('<@', '<<', '2>', '>&', '>>', '>@')
+    kRedirectPrefixes3 = ('2>@', '2>>', '>>&', '>&@')
+    kRedirectPrefixes4 = ('2>@1',)
+
+    def __init__(self, args):
+        self.args = iter(args)
+
+    def lex(self):
+        try:
+            return self.args.next()
+        except StopIteration:
+            return None
+
+    def look(self):
+        next = self.lex()
+        if next is not None:
+            self.args = itertools.chain([next], self.args)
+        return next
+
+    def parse_redirect(self, tok, length):
+        if len(tok) == length:
+            arg = self.lex()
+            if arg is None:
+                raise ValueError,'Missing argument to %r redirection' % tok
+        else:
+            tok,arg = tok[:length],tok[length:]
+
+        if tok[0] == '2':
+            op = (tok[1:],2)
+        else:
+            op = (tok,)
+        return (op, arg)
+
+    def parse_pipeline(self):
+        if self.look() is None:
+            raise ValueError,"Expected at least one argument to exec"
+
+        commands = [Command([],[])]
+        while 1:
+            arg = self.lex()
+            if arg is None:
+                break
+            elif arg == '|':
+                commands.append(Command([],[]))
+            elif arg == '|&':
+                # Write this as a redirect of stderr; it must come first because
+                # stdout may have already been redirected.
+                commands[-1].redirects.insert(0, (('>&',2),'1'))
+                commands.append(Command([],[]))
+            elif arg[:4] in TclExecCommand.kRedirectPrefixes4:
+                commands[-1].redirects.append(self.parse_redirect(arg, 4))
+            elif arg[:3] in TclExecCommand.kRedirectPrefixes3:
+                commands[-1].redirects.append(self.parse_redirect(arg, 3))
+            elif arg[:2] in TclExecCommand.kRedirectPrefixes2:
+                commands[-1].redirects.append(self.parse_redirect(arg, 2))
+            elif arg[:1] in TclExecCommand.kRedirectPrefixes1:
+                commands[-1].redirects.append(self.parse_redirect(arg, 1))
+            else:
+                commands[-1].args.append(arg)
+
+        return Pipeline(commands, False, pipe_err=True)
+
+    def parse(self):
+        ignoreStderr = False
+        keepNewline = False
+
+        # Parse arguments.
+        while 1:
+            next = self.look()
+            if not isinstance(next, str) or next[0] != '-':
+                break
+
+            if next == '--':
+                self.lex()
+                break
+            elif next == '-ignorestderr':
+                ignoreStderr = True
+            elif next == '-keepnewline':
+                keepNewline = True
+            else:
+                raise ValueError,"Invalid exec argument %r" % next
+
+        return (ignoreStderr, keepNewline, self.parse_pipeline())
+
+###
+
+import unittest
+
+class TestTclLexer(unittest.TestCase):
+    def lex(self, str, *args, **kwargs):
+        return list(TclLexer(str, *args, **kwargs).lex())
+
+    def test_preprocess(self):
+        self.assertEqual(tcl_preprocess('a b'), 'a b')
+        self.assertEqual(tcl_preprocess('a\\\nb c'), 'a b c')
+
+    def test_unquoted(self):
+        self.assertEqual(self.lex('a b c'),
+                         ['a', 'b', 'c'])
+        self.assertEqual(self.lex(r'a\nb\tc\ '),
+                         ['a\nb\tc '])
+        self.assertEqual(self.lex(r'a \\\$b c $\\'),
+                         ['a', r'\$b', 'c', '$\\'])
+
+    def test_braced(self):
+        self.assertEqual(self.lex('a {b c} {}'),
+                         ['a', 'b c', ''])
+        self.assertEqual(self.lex(r'a {b {c\n}}'),
+                         ['a', 'b {c\\n}'])
+        self.assertEqual(self.lex(r'a {b\{}'),
+                         ['a', 'b{'])
+        self.assertEqual(self.lex(r'{*}'), ['*'])
+        self.assertEqual(self.lex(r'{*} a'), ['*', 'a'])
+        self.assertEqual(self.lex(r'{*} a'), ['*', 'a'])
+        self.assertEqual(self.lex('{a\\\n   b}'),
+                         ['a b'])
+
+    def test_quoted(self):
+        self.assertEqual(self.lex('a "b c"'),
+                         ['a', 'b c'])
+
+    def test_terminators(self):
+        self.assertEqual(self.lex('a\nb'),
+                         ['a', (';',), 'b'])
+        self.assertEqual(self.lex('a;b'),
+                         ['a', (';',), 'b'])
+        self.assertEqual(self.lex('a   ;   b'),
+                         ['a', (';',), 'b'])
+
+class TestTclExecCommand(unittest.TestCase):
+    def parse(self, str):
+        return TclExecCommand(list(TclLexer(str).lex())).parse()
+
+    def test_basic(self):
+        self.assertEqual(self.parse('echo hello'),
+                         (False, False,
+                          Pipeline([Command(['echo', 'hello'], [])],
+                                   False, True)))
+        self.assertEqual(self.parse('echo hello | grep hello'),
+                         (False, False,
+                          Pipeline([Command(['echo', 'hello'], []),
+                                    Command(['grep', 'hello'], [])],
+                                   False, True)))
+
+    def test_redirect(self):
+        self.assertEqual(self.parse('echo hello > a >b >>c 2> d |& e'),
+                         (False, False,
+                          Pipeline([Command(['echo', 'hello'],
+                                            [(('>&',2),'1'),
+                                             (('>',),'a'),
+                                             (('>',),'b'),
+                                             (('>>',),'c'),
+                                             (('>',2),'d')]),
+                                    Command(['e'], [])],
+                                   False, True)))
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/src/LLVM/utils/lit/lit/Test.py b/src/LLVM/utils/lit/lit/Test.py
new file mode 100644
index 0000000..db2e032
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/Test.py
@@ -0,0 +1,79 @@
+import os
+
+# Test results.
+
+class TestResult:
+    def __init__(self, name, isFailure):
+        self.name = name
+        self.isFailure = isFailure
+
+PASS        = TestResult('PASS', False)
+XFAIL       = TestResult('XFAIL', False)
+FAIL        = TestResult('FAIL', True)
+XPASS       = TestResult('XPASS', True)
+UNRESOLVED  = TestResult('UNRESOLVED', True)
+UNSUPPORTED = TestResult('UNSUPPORTED', False)
+
+# Test classes.
+
+class TestFormat:
+    """TestFormat - Test information provider."""
+
+    def __init__(self, name):
+        self.name = name
+
+class TestSuite:
+    """TestSuite - Information on a group of tests.
+
+    A test suite groups together a set of logically related tests.
+    """
+
+    def __init__(self, name, source_root, exec_root, config):
+        self.name = name
+        self.source_root = source_root
+        self.exec_root = exec_root
+        # The test suite configuration.
+        self.config = config
+
+    def getSourcePath(self, components):
+        return os.path.join(self.source_root, *components)
+
+    def getExecPath(self, components):
+        return os.path.join(self.exec_root, *components)
+
+class Test:
+    """Test - Information on a single test instance."""
+
+    def __init__(self, suite, path_in_suite, config):
+        self.suite = suite
+        self.path_in_suite = path_in_suite
+        self.config = config
+        # The test result code, once complete.
+        self.result = None
+        # Any additional output from the test, once complete.
+        self.output = None
+        # The wall time to execute this test, if timing and once complete.
+        self.elapsed = None
+        # The repeat index of this test, or None.
+        self.index = None
+
+    def copyWithIndex(self, index):
+        import copy
+        res = copy.copy(self)
+        res.index = index
+        return res
+
+    def setResult(self, result, output, elapsed):
+        assert self.result is None, "Test result already set!"
+        self.result = result
+        self.output = output
+        self.elapsed = elapsed
+
+    def getFullName(self):
+        return self.suite.config.name + ' :: ' + '/'.join(self.path_in_suite)
+
+    def getSourcePath(self):
+        return self.suite.getSourcePath(self.path_in_suite)
+
+    def getExecPath(self):
+        return self.suite.getExecPath(self.path_in_suite)
diff --git a/src/LLVM/utils/lit/lit/TestFormats.py b/src/LLVM/utils/lit/lit/TestFormats.py
new file mode 100644
index 0000000..e52d0e4
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/TestFormats.py
@@ -0,0 +1,214 @@
+import os
+
+import Test
+import TestRunner
+import Util
+
+class GoogleTest(object):
+    def __init__(self, test_sub_dir, test_suffix):
+        self.test_sub_dir = str(test_sub_dir)
+        self.test_suffix = str(test_suffix)
+
+    def getGTestTests(self, path, litConfig, localConfig):
+        """getGTestTests(path) - [name]
+
+        Return the tests available in gtest executable.
+
+        Args:
+          path: String path to a gtest executable
+          litConfig: LitConfig instance
+          localConfig: TestingConfig instance"""
+
+        try:
+            lines = Util.capture([path, '--gtest_list_tests'],
+                                 env=localConfig.environment).split('\n')
+        except:
+            litConfig.error("unable to discover google-tests in %r" % path)
+            raise StopIteration
+
+        nested_tests = []
+        for ln in lines:
+            if not ln.strip():
+                continue
+
+            prefix = ''
+            index = 0
+            while ln[index*2:index*2+2] == '  ':
+                index += 1
+            while len(nested_tests) > index:
+                nested_tests.pop()
+            
+            ln = ln[index*2:]
+            if ln.endswith('.'):
+                nested_tests.append(ln)
+            else:
+                yield ''.join(nested_tests) + ln
+
+    def getTestsInDirectory(self, testSuite, path_in_suite,
+                            litConfig, localConfig):
+        source_path = testSuite.getSourcePath(path_in_suite)
+        for filename in os.listdir(source_path):
+            # Check for the one subdirectory (build directory) tests will be in.
+            if filename != self.test_sub_dir:
+                continue
+
+            filepath = os.path.join(source_path, filename)
+            for subfilename in os.listdir(filepath):
+                if subfilename.endswith(self.test_suffix):
+                    execpath = os.path.join(filepath, subfilename)
+
+                    # Discover the tests in this executable.
+                    for name in self.getGTestTests(execpath, litConfig,
+                                                   localConfig):
+                        testPath = path_in_suite + (filename, subfilename, name)
+                        yield Test.Test(testSuite, testPath, localConfig)
+
+    def execute(self, test, litConfig):
+        testPath,testName = os.path.split(test.getSourcePath())
+        while not os.path.exists(testPath):
+            # Handle GTest parametrized and typed tests, whose name includes
+            # some '/'s.
+            testPath, namePrefix = os.path.split(testPath)
+            testName = os.path.join(namePrefix, testName)
+
+        cmd = [testPath, '--gtest_filter=' + testName]
+        if litConfig.useValgrind:
+            cmd = litConfig.valgrindArgs + cmd
+
+        out, err, exitCode = TestRunner.executeCommand(
+            cmd, env=test.config.environment)
+            
+        if not exitCode:
+            return Test.PASS,''
+
+        return Test.FAIL, out + err
+
+###
+
+class FileBasedTest(object):
+    def getTestsInDirectory(self, testSuite, path_in_suite,
+                            litConfig, localConfig):
+        source_path = testSuite.getSourcePath(path_in_suite)
+        for filename in os.listdir(source_path):
+            # Ignore dot files and excluded tests.
+            if (filename.startswith('.') or
+                filename in localConfig.excludes):
+                continue
+
+            filepath = os.path.join(source_path, filename)
+            if not os.path.isdir(filepath):
+                base,ext = os.path.splitext(filename)
+                if ext in localConfig.suffixes:
+                    yield Test.Test(testSuite, path_in_suite + (filename,),
+                                    localConfig)
+
+class ShTest(FileBasedTest):
+    def __init__(self, execute_external = False):
+        self.execute_external = execute_external
+
+    def execute(self, test, litConfig):
+        return TestRunner.executeShTest(test, litConfig,
+                                        self.execute_external)
+
+class TclTest(FileBasedTest):
+    def execute(self, test, litConfig):
+        return TestRunner.executeTclTest(test, litConfig)
+
+###
+
+import re
+import tempfile
+
+class OneCommandPerFileTest:
+    # FIXME: Refactor into generic test for running some command on a directory
+    # of inputs.
+
+    def __init__(self, command, dir, recursive=False,
+                 pattern=".*", useTempInput=False):
+        if isinstance(command, str):
+            self.command = [command]
+        else:
+            self.command = list(command)
+        if dir is not None:
+            dir = str(dir)
+        self.dir = dir
+        self.recursive = bool(recursive)
+        self.pattern = re.compile(pattern)
+        self.useTempInput = useTempInput
+
+    def getTestsInDirectory(self, testSuite, path_in_suite,
+                            litConfig, localConfig):
+        dir = self.dir
+        if dir is None:
+            dir = testSuite.getSourcePath(path_in_suite)
+
+        for dirname,subdirs,filenames in os.walk(dir):
+            if not self.recursive:
+                subdirs[:] = []
+
+            subdirs[:] = [d for d in subdirs
+                          if (d != '.svn' and
+                              d not in localConfig.excludes)]
+
+            for filename in filenames:
+                if (filename.startswith('.') or
+                    not self.pattern.match(filename) or
+                    filename in localConfig.excludes):
+                    continue
+
+                path = os.path.join(dirname,filename)
+                suffix = path[len(dir):]
+                if suffix.startswith(os.sep):
+                    suffix = suffix[1:]
+                test = Test.Test(testSuite,
+                                 path_in_suite + tuple(suffix.split(os.sep)),
+                                 localConfig)
+                # FIXME: Hack?
+                test.source_path = path
+                yield test
+
+    def createTempInput(self, tmp, test):
+        abstract
+
+    def execute(self, test, litConfig):
+        if test.config.unsupported:
+            return (Test.UNSUPPORTED, 'Test is unsupported')
+
+        cmd = list(self.command)
+
+        # If using temp input, create a temporary file and hand it to the
+        # subclass.
+        if self.useTempInput:
+            tmp = tempfile.NamedTemporaryFile(suffix='.cpp')
+            self.createTempInput(tmp, test)
+            tmp.flush()
+            cmd.append(tmp.name)
+        elif hasattr(test, 'source_path'):
+            cmd.append(test.source_path)
+        else:
+            cmd.append(test.getSourcePath())
+
+        out, err, exitCode = TestRunner.executeCommand(cmd)
+
+        diags = out + err
+        if not exitCode and not diags.strip():
+            return Test.PASS,''
+
+        # Try to include some useful information.
+        report = """Command: %s\n""" % ' '.join(["'%s'" % a
+                                                 for a in cmd])
+        if self.useTempInput:
+            report += """Temporary File: %s\n""" % tmp.name
+            report += "--\n%s--\n""" % open(tmp.name).read()
+        report += """Output:\n--\n%s--""" % diags
+
+        return Test.FAIL, report
+
+class SyntaxCheckTest(OneCommandPerFileTest):
+    def __init__(self, compiler, dir, extra_cxx_args=[], *args, **kwargs):
+        cmd = [compiler, '-x', 'c++', '-fsyntax-only'] + extra_cxx_args
+        OneCommandPerFileTest.__init__(self, cmd, dir,
+                                       useTempInput=1, *args, **kwargs)
+
+    def createTempInput(self, tmp, test):
+        print >>tmp, '#include "%s"' % test.source_path
diff --git a/src/LLVM/utils/lit/lit/TestRunner.py b/src/LLVM/utils/lit/lit/TestRunner.py
new file mode 100644
index 0000000..0eb51a8
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/TestRunner.py
@@ -0,0 +1,586 @@
+import os, signal, subprocess, sys
+import StringIO
+
+import ShUtil
+import Test
+import Util
+
+import platform
+import tempfile
+
+class InternalShellError(Exception):
+    def __init__(self, command, message):
+        self.command = command
+        self.message = message
+
+kIsWindows = platform.system() == 'Windows'
+
+# Don't use close_fds on Windows.
+kUseCloseFDs = not kIsWindows
+
+# Use temporary files to replace /dev/null on Windows.
+kAvoidDevNull = kIsWindows
+
+def executeCommand(command, cwd=None, env=None):
+    p = subprocess.Popen(command, cwd=cwd,
+                         stdin=subprocess.PIPE,
+                         stdout=subprocess.PIPE,
+                         stderr=subprocess.PIPE,
+                         env=env)
+    out,err = p.communicate()
+    exitCode = p.wait()
+
+    # Detect Ctrl-C in subprocess.
+    if exitCode == -signal.SIGINT:
+        raise KeyboardInterrupt
+
+    return out, err, exitCode
+
+def executeShCmd(cmd, cfg, cwd, results):
+    if isinstance(cmd, ShUtil.Seq):
+        if cmd.op == ';':
+            res = executeShCmd(cmd.lhs, cfg, cwd, results)
+            return executeShCmd(cmd.rhs, cfg, cwd, results)
+
+        if cmd.op == '&':
+            raise NotImplementedError,"unsupported test command: '&'"
+
+        if cmd.op == '||':
+            res = executeShCmd(cmd.lhs, cfg, cwd, results)
+            if res != 0:
+                res = executeShCmd(cmd.rhs, cfg, cwd, results)
+            return res
+        if cmd.op == '&&':
+            res = executeShCmd(cmd.lhs, cfg, cwd, results)
+            if res is None:
+                return res
+
+            if res == 0:
+                res = executeShCmd(cmd.rhs, cfg, cwd, results)
+            return res
+
+        raise ValueError,'Unknown shell command: %r' % cmd.op
+
+    assert isinstance(cmd, ShUtil.Pipeline)
+    procs = []
+    input = subprocess.PIPE
+    stderrTempFiles = []
+    opened_files = []
+    named_temp_files = []
+    # To avoid deadlock, we use a single stderr stream for piped
+    # output. This is null until we have seen some output using
+    # stderr.
+    for i,j in enumerate(cmd.commands):
+        # Apply the redirections, we use (N,) as a sentinal to indicate stdin,
+        # stdout, stderr for N equal to 0, 1, or 2 respectively. Redirects to or
+        # from a file are represented with a list [file, mode, file-object]
+        # where file-object is initially None.
+        redirects = [(0,), (1,), (2,)]
+        for r in j.redirects:
+            if r[0] == ('>',2):
+                redirects[2] = [r[1], 'w', None]
+            elif r[0] == ('>>',2):
+                redirects[2] = [r[1], 'a', None]
+            elif r[0] == ('>&',2) and r[1] in '012':
+                redirects[2] = redirects[int(r[1])]
+            elif r[0] == ('>&',) or r[0] == ('&>',):
+                redirects[1] = redirects[2] = [r[1], 'w', None]
+            elif r[0] == ('>',):
+                redirects[1] = [r[1], 'w', None]
+            elif r[0] == ('>>',):
+                redirects[1] = [r[1], 'a', None]
+            elif r[0] == ('<',):
+                redirects[0] = [r[1], 'r', None]
+            else:
+                raise NotImplementedError,"Unsupported redirect: %r" % (r,)
+
+        # Map from the final redirections to something subprocess can handle.
+        final_redirects = []
+        for index,r in enumerate(redirects):
+            if r == (0,):
+                result = input
+            elif r == (1,):
+                if index == 0:
+                    raise NotImplementedError,"Unsupported redirect for stdin"
+                elif index == 1:
+                    result = subprocess.PIPE
+                else:
+                    result = subprocess.STDOUT
+            elif r == (2,):
+                if index != 2:
+                    raise NotImplementedError,"Unsupported redirect on stdout"
+                result = subprocess.PIPE
+            else:
+                if r[2] is None:
+                    if kAvoidDevNull and r[0] == '/dev/null':
+                        r[2] = tempfile.TemporaryFile(mode=r[1])
+                    else:
+                        r[2] = open(r[0], r[1])
+                    # Workaround a Win32 and/or subprocess bug when appending.
+                    #
+                    # FIXME: Actually, this is probably an instance of PR6753.
+                    if r[1] == 'a':
+                        r[2].seek(0, 2)
+                    opened_files.append(r[2])
+                result = r[2]
+            final_redirects.append(result)
+
+        stdin, stdout, stderr = final_redirects
+
+        # If stderr wants to come from stdout, but stdout isn't a pipe, then put
+        # stderr on a pipe and treat it as stdout.
+        if (stderr == subprocess.STDOUT and stdout != subprocess.PIPE):
+            stderr = subprocess.PIPE
+            stderrIsStdout = True
+        else:
+            stderrIsStdout = False
+
+            # Don't allow stderr on a PIPE except for the last
+            # process, this could deadlock.
+            #
+            # FIXME: This is slow, but so is deadlock.
+            if stderr == subprocess.PIPE and j != cmd.commands[-1]:
+                stderr = tempfile.TemporaryFile(mode='w+b')
+                stderrTempFiles.append((i, stderr))
+
+        # Resolve the executable path ourselves.
+        args = list(j.args)
+        args[0] = Util.which(args[0], cfg.environment['PATH'])
+        if not args[0]:
+            raise InternalShellError(j, '%r: command not found' % j.args[0])
+
+        # Replace uses of /dev/null with temporary files.
+        if kAvoidDevNull:
+            for i,arg in enumerate(args):
+                if arg == "/dev/null":
+                    f = tempfile.NamedTemporaryFile(delete=False)
+                    f.close()
+                    named_temp_files.append(f.name)
+                    args[i] = f.name
+
+        procs.append(subprocess.Popen(args, cwd=cwd,
+                                      stdin = stdin,
+                                      stdout = stdout,
+                                      stderr = stderr,
+                                      env = cfg.environment,
+                                      close_fds = kUseCloseFDs))
+
+        # Immediately close stdin for any process taking stdin from us.
+        if stdin == subprocess.PIPE:
+            procs[-1].stdin.close()
+            procs[-1].stdin = None
+
+        # Update the current stdin source.
+        if stdout == subprocess.PIPE:
+            input = procs[-1].stdout
+        elif stderrIsStdout:
+            input = procs[-1].stderr
+        else:
+            input = subprocess.PIPE
+
+    # FIXME: There is probably still deadlock potential here. Yawn.
+    procData = [None] * len(procs)
+    procData[-1] = procs[-1].communicate()
+
+    for i in range(len(procs) - 1):
+        if procs[i].stdout is not None:
+            out = procs[i].stdout.read()
+        else:
+            out = ''
+        if procs[i].stderr is not None:
+            err = procs[i].stderr.read()
+        else:
+            err = ''
+        procData[i] = (out,err)
+
+    # Read stderr out of the temp files.
+    for i,f in stderrTempFiles:
+        f.seek(0, 0)
+        procData[i] = (procData[i][0], f.read())
+
+    exitCode = None
+    for i,(out,err) in enumerate(procData):
+        res = procs[i].wait()
+        # Detect Ctrl-C in subprocess.
+        if res == -signal.SIGINT:
+            raise KeyboardInterrupt
+
+        results.append((cmd.commands[i], out, err, res))
+        if cmd.pipe_err:
+            # Python treats the exit code as a signed char.
+            if res < 0:
+                exitCode = min(exitCode, res)
+            else:
+                exitCode = max(exitCode, res)
+        else:
+            exitCode = res
+
+    # Explicitly close any redirected files.
+    for f in opened_files:
+        f.close()
+
+    # Remove any named temporary files we created.
+    for f in named_temp_files:
+        try:
+            os.remove(f)
+        except OSError:
+            pass
+
+    if cmd.negate:
+        exitCode = not exitCode
+
+    return exitCode
+
+def executeScriptInternal(test, litConfig, tmpBase, commands, cwd):
+    ln = ' &&\n'.join(commands)
+    try:
+        cmd = ShUtil.ShParser(ln, litConfig.isWindows).parse()
+    except:
+        return (Test.FAIL, "shell parser error on: %r" % ln)
+
+    results = []
+    try:
+        exitCode = executeShCmd(cmd, test.config, cwd, results)
+    except InternalShellError,e:
+        out = ''
+        err = e.message
+        exitCode = 255
+
+    out = err = ''
+    for i,(cmd, cmd_out,cmd_err,res) in enumerate(results):
+        out += 'Command %d: %s\n' % (i, ' '.join('"%s"' % s for s in cmd.args))
+        out += 'Command %d Result: %r\n' % (i, res)
+        out += 'Command %d Output:\n%s\n\n' % (i, cmd_out)
+        out += 'Command %d Stderr:\n%s\n\n' % (i, cmd_err)
+
+    return out, err, exitCode
+
+def executeTclScriptInternal(test, litConfig, tmpBase, commands, cwd):
+    import TclUtil
+    cmds = []
+    for ln in commands:
+        # Given the unfortunate way LLVM's test are written, the line gets
+        # backslash substitution done twice.
+        ln = TclUtil.TclLexer(ln).lex_unquoted(process_all = True)
+
+        try:
+            tokens = list(TclUtil.TclLexer(ln).lex())
+        except:
+            return (Test.FAIL, "Tcl lexer error on: %r" % ln)
+
+        # Validate there are no control tokens.
+        for t in tokens:
+            if not isinstance(t, str):
+                return (Test.FAIL,
+                        "Invalid test line: %r containing %r" % (ln, t))
+
+        try:
+            cmds.append(TclUtil.TclExecCommand(tokens).parse_pipeline())
+        except:
+            return (Test.FAIL, "Tcl 'exec' parse error on: %r" % ln)
+
+    if litConfig.useValgrind:
+        for pipeline in cmds:
+            if pipeline.commands:
+                # Only valgrind the first command in each pipeline, to avoid
+                # valgrinding things like grep, not, and FileCheck.
+                cmd = pipeline.commands[0]
+                cmd.args = litConfig.valgrindArgs + cmd.args
+
+    cmd = cmds[0]
+    for c in cmds[1:]:
+        cmd = ShUtil.Seq(cmd, '&&', c)
+
+    # FIXME: This is lame, we shouldn't need bash. See PR5240.
+    bashPath = litConfig.getBashPath()
+    if litConfig.useTclAsSh and bashPath:
+        script = tmpBase + '.script'
+
+        # Write script file
+        f = open(script,'w')
+        print >>f, 'set -o pipefail'
+        cmd.toShell(f, pipefail = True)
+        f.close()
+
+        if 0:
+            print >>sys.stdout, cmd
+            print >>sys.stdout, open(script).read()
+            print >>sys.stdout
+            return '', '', 0
+
+        command = [litConfig.getBashPath(), script]
+        out,err,exitCode = executeCommand(command, cwd=cwd,
+                                          env=test.config.environment)
+
+        return out,err,exitCode
+    else:
+        results = []
+        try:
+            exitCode = executeShCmd(cmd, test.config, cwd, results)
+        except InternalShellError,e:
+            results.append((e.command, '', e.message + '\n', 255))
+            exitCode = 255
+
+    out = err = ''
+
+    for i,(cmd, cmd_out, cmd_err, res) in enumerate(results):
+        out += 'Command %d: %s\n' % (i, ' '.join('"%s"' % s for s in cmd.args))
+        out += 'Command %d Result: %r\n' % (i, res)
+        out += 'Command %d Output:\n%s\n\n' % (i, cmd_out)
+        out += 'Command %d Stderr:\n%s\n\n' % (i, cmd_err)
+
+    return out, err, exitCode
+
+def executeScript(test, litConfig, tmpBase, commands, cwd):
+    script = tmpBase + '.script'
+    if litConfig.isWindows:
+        script += '.bat'
+
+    # Write script file
+    f = open(script,'w')
+    if litConfig.isWindows:
+        f.write('\nif %ERRORLEVEL% NEQ 0 EXIT\n'.join(commands))
+    else:
+        f.write(' &&\n'.join(commands))
+    f.write('\n')
+    f.close()
+
+    if litConfig.isWindows:
+        command = ['cmd','/c', script]
+    else:
+        command = ['/bin/sh', script]
+        if litConfig.useValgrind:
+            # FIXME: Running valgrind on sh is overkill. We probably could just
+            # run on clang with no real loss.
+            command = litConfig.valgrindArgs + command
+
+    return executeCommand(command, cwd=cwd, env=test.config.environment)
+
+def isExpectedFail(xfails, xtargets, target_triple):
+    # Check if any xfail matches this target.
+    for item in xfails:
+        if item == '*' or item in target_triple:
+            break
+    else:
+        return False
+
+    # If so, see if it is expected to pass on this target.
+    #
+    # FIXME: Rename XTARGET to something that makes sense, like XPASS.
+    for item in xtargets:
+        if item == '*' or item in target_triple:
+            return False
+
+    return True
+
+def parseIntegratedTestScript(test, normalize_slashes=False):
+    """parseIntegratedTestScript - Scan an LLVM/Clang style integrated test
+    script and extract the lines to 'RUN' as well as 'XFAIL' and 'XTARGET'
+    information. The RUN lines also will have variable substitution performed.
+    """
+
+    # Get the temporary location, this is always relative to the test suite
+    # root, not test source root.
+    #
+    # FIXME: This should not be here?
+    sourcepath = test.getSourcePath()
+    sourcedir = os.path.dirname(sourcepath)
+    execpath = test.getExecPath()
+    execdir,execbase = os.path.split(execpath)
+    tmpBase = os.path.join(execdir, 'Output', execbase)
+    if test.index is not None:
+        tmpBase += '_%d' % test.index
+
+    # Normalize slashes, if requested.
+    if normalize_slashes:
+        sourcepath = sourcepath.replace('\\', '/')
+        sourcedir = sourcedir.replace('\\', '/')
+        tmpBase = tmpBase.replace('\\', '/')
+
+    # We use #_MARKER_# to hide %% while we do the other substitutions.
+    substitutions = [('%%', '#_MARKER_#')]
+    substitutions.extend(test.config.substitutions)
+    substitutions.extend([('%s', sourcepath),
+                          ('%S', sourcedir),
+                          ('%p', sourcedir),
+                          ('%t', tmpBase + '.tmp'),
+                          # FIXME: Remove this once we kill DejaGNU.
+                          ('%abs_tmp', tmpBase + '.tmp'),
+                          ('#_MARKER_#', '%')])
+
+    # Collect the test lines from the script.
+    script = []
+    xfails = []
+    xtargets = []
+    requires = []
+    for ln in open(sourcepath):
+        if 'RUN:' in ln:
+            # Isolate the command to run.
+            index = ln.index('RUN:')
+            ln = ln[index+4:]
+
+            # Trim trailing whitespace.
+            ln = ln.rstrip()
+
+            # Collapse lines with trailing '\\'.
+            if script and script[-1][-1] == '\\':
+                script[-1] = script[-1][:-1] + ln
+            else:
+                script.append(ln)
+        elif 'XFAIL:' in ln:
+            items = ln[ln.index('XFAIL:') + 6:].split(',')
+            xfails.extend([s.strip() for s in items])
+        elif 'XTARGET:' in ln:
+            items = ln[ln.index('XTARGET:') + 8:].split(',')
+            xtargets.extend([s.strip() for s in items])
+        elif 'REQUIRES:' in ln:
+            items = ln[ln.index('REQUIRES:') + 9:].split(',')
+            requires.extend([s.strip() for s in items])
+        elif 'END.' in ln:
+            # Check for END. lines.
+            if ln[ln.index('END.'):].strip() == 'END.':
+                break
+
+    # Apply substitutions to the script.
+    def processLine(ln):
+        # Apply substitutions
+        for a,b in substitutions:
+            ln = ln.replace(a,b)
+
+        # Strip the trailing newline and any extra whitespace.
+        return ln.strip()
+    script = map(processLine, script)
+
+    # Verify the script contains a run line.
+    if not script:
+        return (Test.UNRESOLVED, "Test has no run line!")
+
+    # Check for unterminated run lines.
+    if script[-1][-1] == '\\':
+        return (Test.UNRESOLVED, "Test has unterminated run lines (with '\\')")
+
+    # Check that we have the required features:
+    missing_required_features = [f for f in requires
+                                 if f not in test.config.available_features]
+    if missing_required_features:
+        msg = ', '.join(missing_required_features)
+        return (Test.UNSUPPORTED,
+                "Test requires the following features: %s" % msg)
+
+    isXFail = isExpectedFail(xfails, xtargets, test.suite.config.target_triple)
+    return script,isXFail,tmpBase,execdir
+
+def formatTestOutput(status, out, err, exitCode, failDueToStderr, script):
+    output = StringIO.StringIO()
+    print >>output, "Script:"
+    print >>output, "--"
+    print >>output, '\n'.join(script)
+    print >>output, "--"
+    print >>output, "Exit Code: %r" % exitCode,
+    if failDueToStderr:
+        print >>output, "(but there was output on stderr)"
+    else:
+        print >>output
+    if out:
+        print >>output, "Command Output (stdout):"
+        print >>output, "--"
+        output.write(out)
+        print >>output, "--"
+    if err:
+        print >>output, "Command Output (stderr):"
+        print >>output, "--"
+        output.write(err)
+        print >>output, "--"
+    return (status, output.getvalue())
+
+def executeTclTest(test, litConfig):
+    if test.config.unsupported:
+        return (Test.UNSUPPORTED, 'Test is unsupported')
+
+    # Parse the test script, normalizing slashes in substitutions on Windows
+    # (since otherwise Tcl style lexing will treat them as escapes).
+    res = parseIntegratedTestScript(test, normalize_slashes=kIsWindows)
+    if len(res) == 2:
+        return res
+
+    script, isXFail, tmpBase, execdir = res
+
+    if litConfig.noExecute:
+        return (Test.PASS, '')
+
+    # Create the output directory if it does not already exist.
+    Util.mkdir_p(os.path.dirname(tmpBase))
+
+    res = executeTclScriptInternal(test, litConfig, tmpBase, script, execdir)
+    if len(res) == 2:
+        return res
+
+    # Test for failure. In addition to the exit code, Tcl commands are
+    # considered to fail if there is any standard error output.
+    out,err,exitCode = res
+    if isXFail:
+        ok = exitCode != 0 or err
+        if ok:
+            status = Test.XFAIL
+        else:
+            status = Test.XPASS
+    else:
+        ok = exitCode == 0 and not err
+        if ok:
+            status = Test.PASS
+        else:
+            status = Test.FAIL
+
+    if ok:
+        return (status,'')
+
+    # Set a flag for formatTestOutput so it can explain why the test was
+    # considered to have failed, despite having an exit code of 0.
+    failDueToStderr = exitCode == 0 and err
+
+    return formatTestOutput(status, out, err, exitCode, failDueToStderr, script)
+
+def executeShTest(test, litConfig, useExternalSh):
+    if test.config.unsupported:
+        return (Test.UNSUPPORTED, 'Test is unsupported')
+
+    res = parseIntegratedTestScript(test)
+    if len(res) == 2:
+        return res
+
+    script, isXFail, tmpBase, execdir = res
+
+    if litConfig.noExecute:
+        return (Test.PASS, '')
+
+    # Create the output directory if it does not already exist.
+    Util.mkdir_p(os.path.dirname(tmpBase))
+
+    if useExternalSh:
+        res = executeScript(test, litConfig, tmpBase, script, execdir)
+    else:
+        res = executeScriptInternal(test, litConfig, tmpBase, script, execdir)
+    if len(res) == 2:
+        return res
+
+    out,err,exitCode = res
+    if isXFail:
+        ok = exitCode != 0
+        if ok:
+            status = Test.XFAIL
+        else:
+            status = Test.XPASS
+    else:
+        ok = exitCode == 0
+        if ok:
+            status = Test.PASS
+        else:
+            status = Test.FAIL
+
+    if ok:
+        return (status,'')
+
+    # Sh tests are not considered to fail just from stderr output.
+    failDueToStderr = False
+
+    return formatTestOutput(status, out, err, exitCode, failDueToStderr, script)
diff --git a/src/LLVM/utils/lit/lit/TestingConfig.py b/src/LLVM/utils/lit/lit/TestingConfig.py
new file mode 100644
index 0000000..5c1b273
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/TestingConfig.py
@@ -0,0 +1,101 @@
+import os
+
+class TestingConfig:
+    """"
+    TestingConfig - Information on the tests inside a suite.
+    """
+
+    @staticmethod
+    def frompath(path, parent, litConfig, mustExist, config = None):
+        if config is None:
+            # Set the environment based on the command line arguments.
+            environment = {
+                'LD_LIBRARY_PATH' : os.environ.get('LD_LIBRARY_PATH',''),
+                'PATH' : os.pathsep.join(litConfig.path +
+                                         [os.environ.get('PATH','')]),
+                'PATHEXT' : os.environ.get('PATHEXT',''),
+                'SYSTEMROOT' : os.environ.get('SYSTEMROOT',''),
+                'LLVM_DISABLE_CRT_DEBUG' : '1',
+                }
+
+            config = TestingConfig(parent,
+                                   name = '<unnamed>',
+                                   suffixes = set(),
+                                   test_format = None,
+                                   environment = environment,
+                                   substitutions = [],
+                                   unsupported = False,
+                                   on_clone = None,
+                                   test_exec_root = None,
+                                   test_source_root = None,
+                                   excludes = [],
+                                   available_features = [])
+
+        if os.path.exists(path):
+            # FIXME: Improve detection and error reporting of errors in the
+            # config file.
+            f = open(path)
+            cfg_globals = dict(globals())
+            cfg_globals['config'] = config
+            cfg_globals['lit'] = litConfig
+            cfg_globals['__file__'] = path
+            try:
+                exec f in cfg_globals
+            except SystemExit,status:
+                # We allow normal system exit inside a config file to just
+                # return control without error.
+                if status.args:
+                    raise
+            f.close()
+        elif mustExist:
+            litConfig.fatal('unable to load config from %r ' % path)
+
+        config.finish(litConfig)
+        return config
+
+    def __init__(self, parent, name, suffixes, test_format,
+                 environment, substitutions, unsupported, on_clone,
+                 test_exec_root, test_source_root, excludes,
+                 available_features):
+        self.parent = parent
+        self.name = str(name)
+        self.suffixes = set(suffixes)
+        self.test_format = test_format
+        self.environment = dict(environment)
+        self.substitutions = list(substitutions)
+        self.unsupported = unsupported
+        self.on_clone = on_clone
+        self.test_exec_root = test_exec_root
+        self.test_source_root = test_source_root
+        self.excludes = set(excludes)
+        self.available_features = set(available_features)
+
+    def clone(self, path):
+        # FIXME: Chain implementations?
+        #
+        # FIXME: Allow extra parameters?
+        cfg = TestingConfig(self, self.name, self.suffixes, self.test_format,
+                            self.environment, self.substitutions,
+                            self.unsupported, self.on_clone,
+                            self.test_exec_root, self.test_source_root,
+                            self.excludes, self.available_features)
+        if cfg.on_clone:
+            cfg.on_clone(self, cfg, path)
+        return cfg
+
+    def finish(self, litConfig):
+        """finish() - Finish this config object, after loading is complete."""
+
+        self.name = str(self.name)
+        self.suffixes = set(self.suffixes)
+        self.environment = dict(self.environment)
+        self.substitutions = list(self.substitutions)
+        if self.test_exec_root is not None:
+            # FIXME: This should really only be suite in test suite config
+            # files. Should we distinguish them?
+            self.test_exec_root = str(self.test_exec_root)
+        if self.test_source_root is not None:
+            # FIXME: This should really only be suite in test suite config
+            # files. Should we distinguish them?
+            self.test_source_root = str(self.test_source_root)
+        self.excludes = set(self.excludes)
diff --git a/src/LLVM/utils/lit/lit/Util.py b/src/LLVM/utils/lit/lit/Util.py
new file mode 100644
index 0000000..414b714
--- /dev/null
+++ b/src/LLVM/utils/lit/lit/Util.py
@@ -0,0 +1,125 @@
+import os, sys
+
+def detectCPUs():
+    """
+    Detects the number of CPUs on a system. Cribbed from pp.
+    """
+    # Linux, Unix and MacOS:
+    if hasattr(os, "sysconf"):
+        if os.sysconf_names.has_key("SC_NPROCESSORS_ONLN"):
+            # Linux & Unix:
+            ncpus = os.sysconf("SC_NPROCESSORS_ONLN")
+            if isinstance(ncpus, int) and ncpus > 0:
+                return ncpus
+        else: # OSX:
+            return int(os.popen2("sysctl -n hw.ncpu")[1].read())
+    # Windows:
+    if os.environ.has_key("NUMBER_OF_PROCESSORS"):
+        ncpus = int(os.environ["NUMBER_OF_PROCESSORS"])
+        if ncpus > 0:
+            return ncpus
+    return 1 # Default
+
+def mkdir_p(path):
+    """mkdir_p(path) - Make the "path" directory, if it does not exist; this
+    will also make directories for any missing parent directories."""
+    import errno
+
+    if not path or os.path.exists(path):
+        return
+
+    parent = os.path.dirname(path) 
+    if parent != path:
+        mkdir_p(parent)
+
+    try:
+        os.mkdir(path)
+    except OSError,e:
+        # Ignore EEXIST, which may occur during a race condition.
+        if e.errno != errno.EEXIST:
+            raise
+
+def capture(args, env=None):
+    import subprocess
+    """capture(command) - Run the given command (or argv list) in a shell and
+    return the standard output."""
+    p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+                         env=env)
+    out,_ = p.communicate()
+    return out
+
+def which(command, paths = None):
+    """which(command, [paths]) - Look up the given command in the paths string
+    (or the PATH environment variable, if unspecified)."""
+
+    if paths is None:
+        paths = os.environ.get('PATH','')
+
+    # Check for absolute match first.
+    if os.path.exists(command):
+        return command
+
+    # Would be nice if Python had a lib function for this.
+    if not paths:
+        paths = os.defpath
+
+    # Get suffixes to search.
+    pathext = os.environ.get('PATHEXT', '').split(os.pathsep)
+
+    # Search the paths...
+    for path in paths.split(os.pathsep):
+        for ext in pathext:
+            p = os.path.join(path, command + ext)
+            if os.path.exists(p):
+                return p
+
+    return None
+
+def printHistogram(items, title = 'Items'):
+    import itertools, math
+
+    items.sort(key = lambda (_,v): v)
+
+    maxValue = max([v for _,v in items])
+
+    # Select first "nice" bar height that produces more than 10 bars.
+    power = int(math.ceil(math.log(maxValue, 10)))
+    for inc in itertools.cycle((5, 2, 2.5, 1)):
+        barH = inc * 10**power
+        N = int(math.ceil(maxValue / barH))
+        if N > 10:
+            break
+        elif inc == 1:
+            power -= 1
+
+    histo = [set() for i in range(N)]
+    for name,v in items:
+        bin = min(int(N * v/maxValue), N-1)
+        histo[bin].add(name)
+
+    barW = 40
+    hr = '-' * (barW + 34)
+    print '\nSlowest %s:' % title
+    print hr
+    for name,value in items[-20:]:
+        print '%.2fs: %s' % (value, name)
+    print '\n%s Times:' % title
+    print hr
+    pDigits = int(math.ceil(math.log(maxValue, 10)))
+    pfDigits = max(0, 3-pDigits)
+    if pfDigits:
+        pDigits += pfDigits + 1
+    cDigits = int(math.ceil(math.log(len(items), 10)))
+    print "[%s] :: [%s] :: [%s]" % ('Range'.center((pDigits+1)*2 + 3),
+                                    'Percentage'.center(barW),
+                                    'Count'.center(cDigits*2 + 1))
+    print hr
+    for i,row in enumerate(histo):
+        pct = float(len(row)) / len(items)
+        w = int(barW * pct)
+        print "[%*.*fs,%*.*fs)" % (pDigits, pfDigits, i*barH,
+                                   pDigits, pfDigits, (i+1)*barH),
+        print ":: [%s%s] :: [%*d/%*d]" % ('*'*w, ' '*(barW-w),
+                                          cDigits, len(row),
+                                          cDigits, len(items))
+
diff --git a/src/LLVM/utils/lit/setup.py b/src/LLVM/utils/lit/setup.py
new file mode 100644
index 0000000..e6ae3d8
--- /dev/null
+++ b/src/LLVM/utils/lit/setup.py
@@ -0,0 +1,69 @@
+import lit
+
+# FIXME: Support distutils?
+from setuptools import setup, find_packages
+setup(
+    name = "Lit",
+    version = lit.__version__,
+
+    author = lit.__author__,
+    author_email = lit.__email__,
+    url = 'http://llvm.org',
+    license = 'BSD',
+
+    description = "A Software Testing Tool",
+    keywords = 'test C++ automatic discovery',
+    long_description = """\
+Lit
++++
+
+About
+=====
+
+Lit is a portable tool for executing LLVM and Clang style test suites,
+summarizing their results, and providing indication of failures. Lit is designed
+to be a lightweight testing tool with as simple a user interface as possible.
+
+
+Features
+========
+
+ * Portable!
+ * Flexible test discovery.
+ * Parallel test execution.
+ * Support for multiple test formats and test suite designs.
+
+
+Documentation
+=============
+
+The offical Lit documentation is in the man page, available online in the `LLVM
+Command Guide http://llvm.org/cmds/lit.html`_.
+
+
+Source
+======
+
+The Lit source is available as part of LLVM, in the `LLVM SVN repository
+<http://llvm.org/svn/llvm-project/llvm/trunk/utils/lit`_.
+""",
+
+    classifiers=[
+        'Development Status :: 3 - Alpha',
+        'Environment :: Console',
+        'Intended Audience :: Developers',
+        'License :: OSI Approved :: University of Illinois/NCSA Open Source License',
+        'Natural Language :: English',
+        'Operating System :: OS Independent',
+        'Progamming Language :: Python',
+        'Topic :: Software Development :: Testing',
+        ],
+
+    zip_safe = False,
+    packages = find_packages(),
+    entry_points = {
+        'console_scripts': [
+            'lit = lit:main',
+            ],
+        }
+)
diff --git a/src/LLVM/utils/llvm-native-gcc b/src/LLVM/utils/llvm-native-gcc
new file mode 100644
index 0000000..f34e02d
--- /dev/null
+++ b/src/LLVM/utils/llvm-native-gcc
@@ -0,0 +1,249 @@
+#!/usr/bin/perl

+# Wrapper around LLVM tools to generate a native .o from llvm-gcc using an

+# LLVM back-end (CBE by default).

+

+# set up defaults.

+$Verbose = 0;

+$SaveTemps = 1;

+$PreprocessOnly = 0;

+$CompileDontLink = 0;

+$Backend = 'cbe';

+chomp ($ProgramName = `basename $0`);

+

+sub boldprint {

+	print "", @_, "";

+}

+

+# process command-line options.

+# most of these are passed on to llvm-gcc.

+$GCCOptions = "";

+for ($i = 0; $i <= $#ARGV; ++$i) {	

+	if ($ARGV[$i] =~ /-mllvm-backend=([a-z0-9]*)/) {

+		$Backend = $1;

+		if ($ProgramName =~ /llvm-native-gcc/) {

+			splice (@ARGV, $i, 1);

+			--$i;

+		}

+	} elsif ($ARGV[$i] eq "-E") {

+		$PreprocessOnly = 1;

+	} elsif ($ARGV[$i] eq "-c") {

+		$GCCOptions .= " " . $ARGV[$i];

+		$CompileDontLink = 1;

+	} elsif ($ARGV[$i] eq "-v") {

+		$GCCOptions .= " " . $ARGV[$i];

+		$Verbose = 1;

+	} elsif ($ARGV[$i] eq "-o") {

+		$OutputFile = $ARGV[$i + 1];

+	} elsif ($ARGV[$i] eq "-save-temps") {

+		$GCCOptions .= " " . $ARGV[$i];

+		$SaveTemps = 1;

+	} elsif ($ARGV[$i] =~ /\.bc$/) {

+		push (@BytecodeFiles, $ARGV[$i]);

+	} elsif ($ARGV[$i] =~ /^-L/) {

+		$GCCOptions .= " " . $ARGV[$i];

+		push (@LibDirs, $ARGV[$i]);

+	} elsif ($ARGV[$i] =~ /^-l/) {

+		$GCCOptions .= " " . $ARGV[$i];

+		push (@Libs, $ARGV[$i]);

+	} elsif ($ARGV[$i] =~ /\.(c|cpp|cc|i|ii|C)$/) {

+		$LastCFile = $ARGV[$i];

+	}

+}

+

+sub GetDefaultOutputFileName {

+	my $DefaultOutputFileBase;

+

+	if ($ProgramName =~ /llvm-native-gcc/) {

+		$DefaultOutputFileBase = $LastCFile;

+	} elsif ($ProgramName =~ /native-build/) {

+		$DefaultOutputFileBase = $BytecodeFiles[0];

+	}

+

+	my $def = $DefaultOutputFileBase;

+

+	die "Can't figure out name of output file.\n"

+		unless $DefaultOutputFileBase

+			   && (($ProgramName !~ /native-build/)

+				   || $#BytecodeFiles == 0);

+

+	print "Warning: defaulting output file name ",

+		"based on '$DefaultOutputFileBase'\n" if $Verbose;

+

+	if ($ProgramName =~ /llvm-native-gcc/) {

+		$def =~ s/\.(c|cpp|cc|i|ii|C)$/.o/;

+	} elsif ($ProgramName =~ /native-build/) {

+		$def =~ s/\.bc$/.$Backend/;

+		if ($CompileDontLink) {

+			$def .= ".o";

+		}

+	}

+

+	return $def;

+}

+

+# run a command, optionally echoing, and quitting if it fails:

+sub run {

+	my $command = join(" ", @_);

+	print "$command\n" if $Verbose;

+	$command =~ s/\"/\\\"/g;

+	system $command and die "$0: $command failed";

+}

+

+sub LinkBytecodeFilesIntoTemporary {

+	my $FinalOutputFileName = shift @_;

+	my @BytecodeFiles = @_;

+

+	my $BCFiles = join (" ", @BytecodeFiles);

+	my $LinkedBCFile;

+	if ($SaveTemps) {

+		$LinkedBCFile = "${FinalOutputFileName}.llvm.bc";

+	} else {

+		$LinkedBCFile = "/tmp/nativebuild-$$.llvm.bc";

+	}

+	run "llvm-link -o $LinkedBCFile $BCFiles";

+	return $LinkedBCFile;

+}

+

+sub CompileBytecodeToNative {

+	my ($BCFile, $Backend, $OutputFile) = @_;

+

+	my $GeneratedCode;

+	if ($Backend eq 'cbe') {

+		if ($SaveTemps) {

+			$GeneratedCode = "${OutputFile}.c";

+		} else {

+			$GeneratedCode = "/tmp/nativebuild-$$.c";

+		}

+		run "llc -enable-correct-eh-support -march=c -f -o $GeneratedCode $BCFile";

+	} elsif ($Backend eq 'llc') {

+		if ($SaveTemps) {

+			$GeneratedCode = "${OutputFile}.s";

+		} else {

+			$GeneratedCode = "/tmp/nativebuild-$$.s";

+		}

+		run "llc -enable-correct-eh-support -f -o $GeneratedCode $BCFile";

+	}

+	my $LibDirs = join (" ", @LibDirs);

+	my $Libs = join (" ", @Libs);

+	run "gcc $GCCOptions $GeneratedCode -o $OutputFile $LibDirs $Libs";

+	run "rm $BCFile $GeneratedCode"

+		unless $SaveTemps;

+}

+

+sub CompileCToNative {

+	my ($LLVMGCCCommand, $Backend, $OutputFile) = @_;

+	run $LLVMGCCCommand;

+	if ($PreprocessOnly) {

+		return;

+	}

+	my $BCFile = "${OutputFile}.llvm.bc";

+	if ($CompileDontLink) {

+		run "mv ${OutputFile} $BCFile";

+	} else { # gccld messes with the output file name

+		run "mv ${OutputFile}.bc $BCFile";

+	}

+	my $GeneratedCode;

+	if ($Backend eq 'cbe') {

+		$GeneratedCode = "${OutputFile}.cbe.c";

+		run "llc -enable-correct-eh-support -march=c -f -o $GeneratedCode $BCFile";

+	} elsif ($Backend eq 'llc') {

+		$GeneratedCode = "${OutputFile}.llc.s";

+		run "llc -enable-correct-eh-support -f -o $GeneratedCode $BCFile";

+	}

+	my $NativeGCCOptions = "";

+	if ($CompileDontLink) {

+		$NativeGCCOptions = "-c";

+	}

+	run "gcc $NativeGCCOptions $GeneratedCode -o $OutputFile";

+	run "rm ${OutputFile}.llvm.bc $GeneratedCode"

+		unless $SaveTemps;

+}

+

+# guess the name of the output file, if -o was not specified.

+$OutputFile = GetDefaultOutputFileName () unless $OutputFile;

+print "Output file is $OutputFile\n" if $Verbose;

+# do all the dirty work:

+if ($ProgramName eq /native-build/) {

+	my $LinkedBCFile = LinkBytecodeFilesIntoTemporary (@BytecodeFiles);

+	CompileBytecodeToNative ($LinkedBCFile, $Backend, $OutputFile);

+} elsif ($ProgramName =~ /llvm-native-gcc/) {

+	# build the llvm-gcc command line.

+	$LLVMGCCCommand = join (" ", ("llvm-gcc", @ARGV));

+	CompileCToNative ($LLVMGCCCommand, $Backend, $OutputFile);

+}

+

+# we're done.

+exit 0;

+

+__END__

+

+=pod

+

+=head1 NAME

+

+llvm-native-gcc

+

+=head1 SYNOPSIS

+

+llvm-native-gcc [OPTIONS...] FILE

+

+native-build [OPTIONS...] FILE

+

+=head1 DESCRIPTION

+

+llvm-native-gcc is a wrapper around the LLVM command-line tools which generates

+a native object (.o) file by compiling FILE with llvm-gcc, and then running 

+an LLVM back-end (CBE by default) over the resulting bytecode, and then

+compiling the resulting code to a native object file.

+

+If called as "native-build", it compiles bytecode to native code, and takes

+different options.

+

+=head1 OPTIONS

+

+llvm-native-gcc takes the same options as llvm-gcc. All options

+except -mllvm-backend=... are passed on to llvm-gcc.

+

+=over 4

+

+=item -mllvm-backend=BACKEND

+

+Use BACKEND for native code generation. 

+

+=item -v

+

+Print command lines that llvm-native-gcc runs.

+

+=item -o FILE

+

+llvm-native-gcc tries to guess the name of the llvm-gcc output file by looking

+for this option in the command line. If it can't find it, it finds the last C

+or C++ source file named on the command line, and turns its suffix into .o. See

+BUGS.

+

+=item -save-temps

+

+Save temporary files used by llvm-native-gcc (and llvm-gcc, and gcc).

+

+=back

+

+=head1 BUGS

+

+llvm-native-gcc only handles the case where llvm-gcc compiles a single

+file per invocation.  llvm-native-gcc has weak command-line argument

+parsing and is a poor substitute for making gcc/gcc.c do this stuff.

+

+This manual page does not adequately document native-build mode.

+

+llvm-native-gcc is pretty gross because it represents the blind merging of two

+other scripts that predated it. It could use some code clean-up.

+

+=head1 SEE ALSO

+

+gcc(1)

+

+=head1 AUTHOR

+

+Brian R. Gaeke

+

+=cut

diff --git a/src/LLVM/utils/llvm-native-gxx b/src/LLVM/utils/llvm-native-gxx
new file mode 100644
index 0000000..1e9b0c0
--- /dev/null
+++ b/src/LLVM/utils/llvm-native-gxx
@@ -0,0 +1,249 @@
+#!/usr/bin/perl

+# Wrapper around LLVM tools to generate a native .o from llvm-gxx using an

+# LLVM back-end (CBE by default).

+

+# set up defaults.

+$Verbose = 0;

+$SaveTemps = 1;

+$PreprocessOnly = 0;

+$CompileDontLink = 0;

+$Backend = 'cbe';

+chomp ($ProgramName = `basename $0`);

+

+sub boldprint {

+	print "", @_, "";

+}

+

+# process command-line options.

+# most of these are passed on to llvm-gxx.

+$GCCOptions = "";

+for ($i = 0; $i <= $#ARGV; ++$i) {	

+	if ($ARGV[$i] =~ /-mllvm-backend=([a-z0-9]*)/) {

+		$Backend = $1;

+		if ($ProgramName =~ /llvm-native-gxx/) {

+			splice (@ARGV, $i, 1);

+			--$i;

+		}

+	} elsif ($ARGV[$i] eq "-E") {

+		$PreprocessOnly = 1;

+	} elsif ($ARGV[$i] eq "-c") {

+		$GCCOptions .= " " . $ARGV[$i];

+		$CompileDontLink = 1;

+	} elsif ($ARGV[$i] eq "-v") {

+		$GCCOptions .= " " . $ARGV[$i];

+		$Verbose = 1;

+	} elsif ($ARGV[$i] eq "-o") {

+		$OutputFile = $ARGV[$i + 1];

+	} elsif ($ARGV[$i] eq "-save-temps") {

+		$GCCOptions .= " " . $ARGV[$i];

+		$SaveTemps = 1;

+	} elsif ($ARGV[$i] =~ /\.bc$/) {

+		push (@BytecodeFiles, $ARGV[$i]);

+	} elsif ($ARGV[$i] =~ /^-L/) {

+		$GCCOptions .= " " . $ARGV[$i];

+		push (@LibDirs, $ARGV[$i]);

+	} elsif ($ARGV[$i] =~ /^-l/) {

+		$GCCOptions .= " " . $ARGV[$i];

+		push (@Libs, $ARGV[$i]);

+	} elsif ($ARGV[$i] =~ /\.(c|cpp|cc|i|ii|C)$/) {

+		$LastCFile = $ARGV[$i];

+	}

+}

+

+sub GetDefaultOutputFileName {

+	my $DefaultOutputFileBase;

+

+	if ($ProgramName =~ /llvm-native-gxx/) {

+		$DefaultOutputFileBase = $LastCFile;

+	} elsif ($ProgramName =~ /native-build/) {

+		$DefaultOutputFileBase = $BytecodeFiles[0];

+	}

+

+	my $def = $DefaultOutputFileBase;

+

+	die "Can't figure out name of output file.\n"

+		unless $DefaultOutputFileBase

+			   && (($ProgramName !~ /native-build/)

+				   || $#BytecodeFiles == 0);

+

+	print "Warning: defaulting output file name ",

+		"based on '$DefaultOutputFileBase'\n" if $Verbose;

+

+	if ($ProgramName =~ /llvm-native-gxx/) {

+		$def =~ s/\.(c|cpp|cc|i|ii|C)$/.o/;

+	} elsif ($ProgramName =~ /native-build/) {

+		$def =~ s/\.bc$/.$Backend/;

+		if ($CompileDontLink) {

+			$def .= ".o";

+		}

+	}

+

+	return $def;

+}

+

+# run a command, optionally echoing, and quitting if it fails:

+sub run {

+	my $command = join(" ", @_);

+	print "$command\n" if $Verbose;

+	$command =~ s/\"/\\\"/g;

+	system $command and die "$0: $command failed";

+}

+

+sub LinkBytecodeFilesIntoTemporary {

+	my $FinalOutputFileName = shift @_;

+	my @BytecodeFiles = @_;

+

+	my $BCFiles = join (" ", @BytecodeFiles);

+	my $LinkedBCFile;

+	if ($SaveTemps) {

+		$LinkedBCFile = "${FinalOutputFileName}.llvm.bc";

+	} else {

+		$LinkedBCFile = "/tmp/nativebuild-$$.llvm.bc";

+	}

+	run "llvm-link -o $LinkedBCFile $BCFiles";

+	return $LinkedBCFile;

+}

+

+sub CompileBytecodeToNative {

+	my ($BCFile, $Backend, $OutputFile) = @_;

+

+	my $GeneratedCode;

+	if ($Backend eq 'cbe') {

+		if ($SaveTemps) {

+			$GeneratedCode = "${OutputFile}.c";

+		} else {

+			$GeneratedCode = "/tmp/nativebuild-$$.c";

+		}

+		run "llc -march=c -f -o $GeneratedCode $BCFile";

+	} elsif ($Backend eq 'llc') {

+		if ($SaveTemps) {

+			$GeneratedCode = "${OutputFile}.s";

+		} else {

+			$GeneratedCode = "/tmp/nativebuild-$$.s";

+		}

+		run "llc -f -o $GeneratedCode $BCFile";

+	}

+	my $LibDirs = join (" ", @LibDirs);

+	my $Libs = join (" ", @Libs);

+	run "gcc $GCCOptions $GeneratedCode -o $OutputFile $LibDirs $Libs";

+	run "rm $BCFile $GeneratedCode"

+		unless $SaveTemps;

+}

+

+sub CompileCToNative {

+	my ($LLVMGCCCommand, $Backend, $OutputFile) = @_;

+	run $LLVMGCCCommand;

+	if ($PreprocessOnly) {

+		return;

+	}

+	my $BCFile = "${OutputFile}.llvm.bc";

+	if ($CompileDontLink) {

+		run "mv ${OutputFile} $BCFile";

+	} else { # gccld messes with the output file name

+		run "mv ${OutputFile}.bc $BCFile";

+	}

+	my $GeneratedCode;

+	if ($Backend eq 'cbe') {

+		$GeneratedCode = "${OutputFile}.cbe.c";

+		run "llc -march=c -f -o $GeneratedCode $BCFile";

+	} elsif ($Backend eq 'llc') {

+		$GeneratedCode = "${OutputFile}.llc.s";

+		run "llc -f -o $GeneratedCode $BCFile";

+	}

+	my $NativeGCCOptions = "";

+	if ($CompileDontLink) {

+		$NativeGCCOptions = "-c";

+	}

+	run "gcc $NativeGCCOptions $GeneratedCode -o $OutputFile";

+	run "rm ${OutputFile}.llvm.bc $GeneratedCode"

+		unless $SaveTemps;

+}

+

+# guess the name of the output file, if -o was not specified.

+$OutputFile = GetDefaultOutputFileName () unless $OutputFile;

+print "Output file is $OutputFile\n" if $Verbose;

+# do all the dirty work:

+if ($ProgramName eq /native-build/) {

+	my $LinkedBCFile = LinkBytecodeFilesIntoTemporary (@BytecodeFiles);

+	CompileBytecodeToNative ($LinkedBCFile, $Backend, $OutputFile);

+} elsif ($ProgramName =~ /llvm-native-gxx/) {

+	# build the llvm-gxx command line.

+	$LLVMGCCCommand = join (" ", ("llvm-g++", @ARGV));

+	CompileCToNative ($LLVMGCCCommand, $Backend, $OutputFile);

+}

+

+# we're done.

+exit 0;

+

+__END__

+

+=pod

+

+=head1 NAME

+

+llvm-native-gxx

+

+=head1 SYNOPSIS

+

+llvm-native-g++ [OPTIONS...] FILE

+

+native-build [OPTIONS...] FILE

+

+=head1 DESCRIPTION

+

+llvm-native-g++ is a wrapper around the LLVM command-line tools which generates

+a native object (.o) file by compiling FILE with llvm-g++, and then running 

+an LLVM back-end (CBE by default) over the resulting bytecode, and then

+compiling the resulting code to a native object file.

+

+If called as "native-build", it compiles bytecode to native code, and takes

+different options.

+

+=head1 OPTIONS

+

+llvm-native-g++ takes the same options as llvm-gcc. All options

+except -mllvm-backend=... are passed on to llvm-g++.

+

+=over 4

+

+=item -mllvm-backend=BACKEND

+

+Use BACKEND for native code generation. 

+

+=item -v

+

+Print command lines that llvm-native-g++ runs.

+

+=item -o FILE

+

+llvm-native-g++ tries to guess the name of the llvm-g++ output file by looking

+for this option in the command line. If it can't find it, it finds the last C

+or C++ source file named on the command line, and turns its suffix into .o. See

+BUGS.

+

+=item -save-temps

+

+Save temporary files used by llvm-native-g++ (and llvm-g++, and g++).

+

+=back

+

+=head1 BUGS

+

+llvm-native-g++ only handles the case where llvm-g++ compiles a single

+file per invocation.  llvm-native-g++ has weak command-line argument

+parsing and is a poor substitute for making g++/g++.c do this stuff.

+

+This manual page does not adequately document native-build mode.

+

+llvm-native-g++ is pretty gross because it represents the blind merging of two

+other scripts that predated it. It could use some code clean-up.

+

+=head1 SEE ALSO

+

+g++(1)

+

+=head1 AUTHOR

+

+Brian R. Gaeke

+

+=cut

diff --git a/src/LLVM/utils/llvm.grm b/src/LLVM/utils/llvm.grm
new file mode 100644
index 0000000..f97c0d1
--- /dev/null
+++ b/src/LLVM/utils/llvm.grm
@@ -0,0 +1,419 @@
+(*
+
+polygen grammar for LLVM assembly language.
+
+This file defines an LLVM assembly language grammar for polygen,
+which is a tool for generating random text based on a grammar.
+It is strictly syntax-based, and makes no attempt to generate
+IR that is semantically valid. Most of the IR produced doesn't
+pass the Verifier.
+
+TODO: Metadata, in all its forms
+TODO: Union types
+
+*)
+
+I ::=   "title:    LLVM assembly language\n"
+      ^ "status:   experimental\n"
+      ^ "audience: LLVM developers\n"
+;
+
+S ::= Module ;
+
+(*
+Define rules for non-keyword tokens. This is currently just a bunch
+of hacks. They don't cover many valid forms of tokens, and they also
+generate some invalid forms of tokens. The LLVM parser has custom
+C++ code to lex these; custom C++ code for emitting them would be
+convenient, but polygen doesn't support that.
+*)
+NonZeroDecimalDigit ::=     1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 ;
+DecimalDigit        ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 ;
+DecimalDigitSeq     ::= DecimalDigit [^ DecimalDigitSeq ];
+HexDigit            ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
+                      | a | b | c | d | e | f ;
+HexDigitSeq         ::= HexDigit [^ HexDigitSeq ];
+StringChar          ::= a | b | c | d | e | f | g | h | i | j | k | l | m
+                      | n | o | p | q | r | s | t | u | v | w | x | y | z ;
+StringConstantSeq   ::= StringChar [^ StringConstantSeq ];
+StringConstant      ::= StringChar [^ StringConstantSeq ];
+EUINT64VAL          ::= NonZeroDecimalDigit [^ DecimalDigitSeq ];
+ESINT64VAL          ::= [ "-" ] ^ EUINT64VAL ;
+EUAPINTVAL          ::= EUINT64VAL ;
+ESAPINTVAL          ::= ESINT64VAL ;
+LOCALVALID          ::= "%" ^ DecimalDigitSeq ;
+GLOBALVALID         ::= "@" ^ DecimalDigitSeq ;
+INTTYPE             ::= "i" ^ EUINT64VAL ;
+GLOBALVAR           ::= "@" ^ StringConstant ;
+LOCALVAR            ::= "%" ^ StringConstant ;
+STRINGCONSTANT      ::= "\"" ^ StringConstant ^ "\"" ;
+ATSTRINGCONSTANT    ::= "@" ^ STRINGCONSTANT ;
+PCTSTRINGCONSTANT   ::= "%" ^ STRINGCONSTANT ;
+LABELSTR            ::= StringConstant ;
+FPVAL               ::= ESAPINTVAL ^ "." ^ EUAPINTVAL | "0x" ^ HexDigitSeq ;
+
+(*
+The rest of this file is derived directly from llvmAsmParser.y.
+*)
+
+ArithmeticOps ::= + OptNW add | fadd | OptNW sub | fsub | OptNW mul | fmul |
+                  udiv | OptExact sdiv | fdiv | urem | srem | frem ;
+LogicalOps    ::= shl | lshr | ashr | and | or | xor;
+CastOps       ::= trunc | zext | sext | fptrunc | fpext | bitcast |
+                  uitofp | sitofp | fptoui | fptosi | inttoptr | ptrtoint ;
+
+IPredicates ::= eq | ne | slt | sgt | sle | sge | ult | ugt | ule | uge ;
+
+FPredicates ::= oeq | one | olt | ogt | ole | oge | ord | uno | ueq | une
+              | ult | ugt | ule | uge | true | false ;
+
+IntType ::= INTTYPE;
+FPType  ::= float | double | "ppc_fp128" | fp128 | "x86_fp80";
+
+LocalName ::= LOCALVAR | STRINGCONSTANT | PCTSTRINGCONSTANT ;
+OptLocalName ::= LocalName | _ ;
+
+OptAddrSpace ::= - addrspace ^ "(" ^ EUINT64VAL ^ ")" | _ ;
+
+OptLocalAssign ::= LocalName "=" | _ ;
+
+GlobalName ::= GLOBALVAR | ATSTRINGCONSTANT ;
+
+OptGlobalAssign ::= GlobalAssign | _ ;
+
+GlobalAssign ::= GlobalName "=" ;
+
+GVInternalLinkage
+  ::= + internal
+ | weak
+ | "weak_odr"
+ | linkonce
+ | "linkonce_odr"
+ | appending
+ | dllexport
+ | common
+ | private
+ | "linker_private"
+ | "linker_private_weak"
+ ;
+
+GVExternalLinkage
+  ::= dllimport
+ | "extern_weak"
+ | + external
+ ;
+
+GVVisibilityStyle
+  ::= + _
+ | default
+ | hidden
+ | protected
+ ;
+
+FunctionDeclareLinkage
+  ::= + _
+ | dllimport
+ | "extern_weak"
+ ;
+
+FunctionDefineLinkage
+  ::= + _
+ | internal
+ | linkonce
+ | "linkonce_odr"
+ | weak
+ | "weak_odr"
+ | dllexport
+ ;
+
+AliasLinkage ::= + _ | weak | "weak_odr" | internal ;
+
+OptCallingConv ::= + _ |
+                 ccc |
+                 fastcc |
+                 coldcc |
+                 "x86_stdcallcc" |
+                 "x86_fastcallcc" |
+                 cc EUINT64VAL ;
+
+ParamAttr ::= zeroext
+ | signext
+ | inreg
+ | sret
+ | noalias
+ | nocapture
+ | byval
+ | nest
+ | align EUINT64VAL
+ ;
+
+OptParamAttrs ::= + _ | OptParamAttrs ParamAttr ;
+
+RetAttr       ::= inreg
+              | zeroext
+              | signext
+              | noalias
+              ;
+
+OptRetAttrs  ::= _
+             | OptRetAttrs RetAttr
+             ;
+
+FuncAttr      ::= noreturn
+ | nounwind
+ | inreg
+ | zeroext
+ | signext
+ | readnone
+ | readonly
+ | inlinehint
+ | alignstack
+ | noinline
+ | alwaysinline
+ | optsize
+ | ssp
+ | sspreq
+ ;
+
+OptFuncAttrs  ::= + _ | OptFuncAttrs FuncAttr ;
+
+OptGC         ::= + _ | gc STRINGCONSTANT ;
+
+OptAlign      ::= + _ | align EUINT64VAL ;
+OptCAlign     ::= + _ | ^ "," align EUINT64VAL ;
+
+SectionString ::= section STRINGCONSTANT ;
+
+OptSection    ::= + _ | SectionString ;
+
+GlobalVarAttributes ::= + _ | ^ "," GlobalVarAttribute GlobalVarAttributes ;
+GlobalVarAttribute  ::= SectionString | align EUINT64VAL ;
+
+PrimType ::= INTTYPE | float | double | "ppc_fp128" | fp128 | "x86_fp80"
+          | - label ;
+
+Types
+  ::= opaque
+ | PrimType
+ | Types OptAddrSpace ^ "*"
+ | SymbolicValueRef
+ | "\\" ^ EUINT64VAL
+ | Types "(" ^ ArgTypeListI ^ ")" OptFuncAttrs
+ | void "(" ^ ArgTypeListI ^ ")" OptFuncAttrs
+ | "[" ^ EUINT64VAL "x" Types ^ "]"
+ | "<" ^ EUINT64VAL "x" Types ^ ">"
+ | "{" TypeListI "}"
+ | "{" ^ "}"
+ | "<" ^ "{" TypeListI "}" ^ ">"
+ | "<" ^ "{" ^ "}" ^ ">"
+ ;
+
+ArgType ::= Types OptParamAttrs ;
+
+ResultTypes ::= Types | void ;
+
+ArgTypeList ::= ArgType | ArgTypeList ^ "," ArgType ;
+
+ArgTypeListI ::= ArgTypeList | ArgTypeList ^ "," "..." | "..." | _ ;
+
+TypeListI ::= Types | TypeListI ^ "," Types ;
+
+ConstVal::= Types "[" ^ ConstVector ^ "]"
+ | Types "[" ^ "]"
+ | Types "c" ^ STRINGCONSTANT
+ | Types "<" ^ ConstVector ^ ">"
+ | Types "{" ConstVector "}"
+ | Types "{" ^ "}"
+ | Types "<" ^ "{" ConstVector "}" ^ ">"
+ | Types "<" ^ "{" ^ "}" ^ ">"
+ | Types null
+ | Types undef
+ | Types SymbolicValueRef
+ | Types ConstExpr
+ | Types zeroinitializer
+ | Types ESINT64VAL
+ | Types ESAPINTVAL
+ | Types EUINT64VAL
+ | Types EUAPINTVAL
+ | Types true
+ | Types false
+ | Types FPVAL ;
+
+ConstExpr::= CastOps "(" ^ ConstVal to Types ^ ")"
+ | getelementptr OptInBounds "(" ^ ConstVal IndexList ^ ")"
+ | select "(" ^ ConstVal ^ "," ConstVal ^ "," ConstVal ^ ")"
+ | ArithmeticOps "(" ^ ConstVal ^ "," ConstVal ^ ")"
+ | LogicalOps "(" ^ ConstVal ^ "," ConstVal ^ ")"
+ | icmp IPredicates "(" ^ ConstVal ^ "," ConstVal ^ ")"
+ | fcmp FPredicates "(" ^ ConstVal ^ "," ConstVal ^ ")"
+ | extractelement "(" ^ ConstVal ^ "," ConstVal ^ ")"
+ | insertelement "(" ^ ConstVal ^ "," ConstVal ^ "," ConstVal ^ ")"
+ | shufflevector "(" ^ ConstVal ^ "," ConstVal ^ "," ConstVal ^ ")"
+ | extractvalue "(" ^ ConstVal ^ ConstantIndexList ^ ")"
+ | insertvalue "(" ^ ConstVal ^ "," ConstVal ^ ConstantIndexList ^ ")" ;
+
+ConstVector ::= ConstVector ^ "," ConstVal | ConstVal ;
+
+GlobalType ::= global | constant ;
+
+ThreadLocal ::= - "thread_local" | _ ;
+
+AliaseeRef ::= ResultTypes SymbolicValueRef
+ | bitcast "(" ^ AliaseeRef to Types ^ ")" ;
+
+Module ::= +++ DefinitionList | --- _ ;
+
+DefinitionList ::= - Definition | + DefinitionList Definition ;
+
+Definition
+  ::= ^ ( +++++ define Function
+ | declare FunctionProto
+ | - module asm AsmBlock
+ | OptLocalAssign type Types
+ | OptGlobalAssign GVVisibilityStyle ThreadLocal OptAddrSpace GlobalType
+   ConstVal GlobalVarAttributes
+ | OptGlobalAssign GVInternalLinkage GVVisibilityStyle ThreadLocal OptAddrSpace
+   GlobalType ConstVal GlobalVarAttributes
+ | OptGlobalAssign GVExternalLinkage GVVisibilityStyle ThreadLocal OptAddrSpace
+   GlobalType Types GlobalVarAttributes
+ | OptGlobalAssign GVVisibilityStyle alias AliasLinkage AliaseeRef
+ | target TargetDefinition
+ | deplibs "=" LibrariesDefinition
+ ) ^ "\n";
+
+AsmBlock ::= STRINGCONSTANT ;
+
+TargetDefinition ::= triple "=" STRINGCONSTANT
+ | datalayout "=" STRINGCONSTANT ;
+
+LibrariesDefinition ::= "[" ( LibList | _ ) "]";
+
+LibList ::= LibList ^ "," STRINGCONSTANT | STRINGCONSTANT ;
+
+ArgListH ::= ArgListH ^ "," Types OptParamAttrs OptLocalName
+ | Types OptParamAttrs OptLocalName ;
+
+ArgList ::= ArgListH | ArgListH ^ "," "..." | "..." | _ ;
+
+FunctionHeaderH ::= OptCallingConv OptRetAttrs ResultTypes
+                  GlobalName ^ "(" ^ ArgList ^ ")"
+                  OptFuncAttrs OptSection OptAlign OptGC ;
+
+BEGIN ::= ( begin | "{" ) ^ "\n";
+
+FunctionHeader ::=
+  FunctionDefineLinkage GVVisibilityStyle FunctionHeaderH BEGIN ;
+
+END ::= ^ ( end | "}" ) ^ "\n";
+
+Function ::= BasicBlockList END ;
+
+FunctionProto ::= FunctionDeclareLinkage GVVisibilityStyle FunctionHeaderH ;
+
+OptSideEffect ::= _ | sideeffect ;
+
+ConstValueRef ::= ESINT64VAL
+ | EUINT64VAL
+ | FPVAL
+ | true
+ | false
+ | null
+ | undef
+ | zeroinitializer
+ | "<" ConstVector ">"
+ | "[" ConstVector "]"
+ | "[" ^ "]"
+ | "c" ^ STRINGCONSTANT
+ | "{" ConstVector "}"
+ | "{" ^ "}"
+ | "<" ^ "{" ConstVector "}" ^ ">"
+ | "<" ^ "{" ^ "}" ^ ">"
+ | ConstExpr
+ | asm OptSideEffect STRINGCONSTANT ^ "," STRINGCONSTANT ;
+
+SymbolicValueRef ::= LOCALVALID
+ | GLOBALVALID
+ | LocalName
+ | GlobalName ;
+
+ValueRef ::= SymbolicValueRef | ConstValueRef;
+
+ResolvedVal ::= Types ValueRef ;
+
+ReturnedVal ::= ResolvedVal | ReturnedVal ^ "," ResolvedVal ;
+
+BasicBlockList ::= BasicBlockList BasicBlock | FunctionHeader BasicBlock ;
+
+BasicBlock ::= InstructionList OptLocalAssign BBTerminatorInst ;
+
+InstructionList ::= +++ InstructionList Inst
+ | - _
+ | ^ LABELSTR ^ ":\n" ;
+
+BBTerminatorInst ::= ^ "  " ^
+ ( ret ReturnedVal
+ | ret void
+ | br label ValueRef
+ | br INTTYPE ValueRef ^ "," label ValueRef ^ "," label ValueRef
+ | switch IntType ValueRef ^ "," label ValueRef "[" JumpTable "]"
+ | switch IntType ValueRef ^ "," label ValueRef "[" ^ "]"
+ | invoke OptCallingConv ResultTypes ValueRef ^ "(" ^ ParamList ^ ")"
+   OptFuncAttrs
+   to label ValueRef unwind label ValueRef
+ | unwind
+ | unreachable ) ^ "\n";
+
+JumpTable ::= JumpTable IntType ConstValueRef ^ "," label ValueRef
+ | IntType ConstValueRef ^ "," label ValueRef ;
+
+Inst ::= ^ "  " ^ OptLocalAssign InstVal ^ "\n";
+
+PHIList ::= Types "[" ValueRef ^ "," ValueRef "]"
+ | PHIList ^ "," "[" ValueRef ^ "," ValueRef "]" ;
+
+ParamList ::= Types OptParamAttrs ValueRef OptParamAttrs
+ | label OptParamAttrs ValueRef OptParamAttrs
+ | ParamList ^ "," Types OptParamAttrs ValueRef OptParamAttrs
+ | ParamList ^ "," label OptParamAttrs ValueRef OptParamAttrs
+ | - _ ;
+
+IndexList ::= _ | IndexList ^ "," ResolvedVal ;
+
+ConstantIndexList ::= "," EUINT64VAL | ConstantIndexList ^ "," EUINT64VAL ;
+
+OptTailCall ::= tail call | call ;
+
+InstVal ::=
+   ArithmeticOps Types ValueRef ^ "," ValueRef
+ | LogicalOps Types ValueRef ^ "," ValueRef
+ | icmp IPredicates Types ValueRef ^ "," ValueRef
+ | fcmp FPredicates Types ValueRef ^ "," ValueRef
+ | CastOps ResolvedVal to Types
+ | select ResolvedVal ^ "," ResolvedVal ^ "," ResolvedVal
+ | "va_arg" ResolvedVal ^ "," Types
+ | extractelement ResolvedVal ^ "," ResolvedVal
+ | insertelement ResolvedVal ^ "," ResolvedVal ^ "," ResolvedVal
+ | shufflevector ResolvedVal ^ "," ResolvedVal ^ "," ResolvedVal
+ | phi PHIList
+ | OptTailCall OptCallingConv ResultTypes ValueRef ^ "(" ^ ParamList ^ ")"
+   OptFuncAttrs
+ | MemoryInst ;
+
+OptVolatile ::= - volatile | _ ;
+OptExact ::= - exact | _ ;
+OptNSW ::= - nsw | _ ;
+OptNUW ::= - nuw | _ ;
+OptNW  ::= OptNUW OptNSW | OptNSW OptNUW ;
+OptInBounds  ::= - inbounds | _ ;
+
+MemoryInst ::= malloc Types OptCAlign
+ | malloc Types ^ "," INTTYPE ValueRef OptCAlign
+ | alloca Types OptCAlign
+ | alloca Types ^ "," INTTYPE ValueRef OptCAlign
+ | free ResolvedVal
+ | OptVolatile load Types ValueRef OptCAlign
+ | OptVolatile store ResolvedVal ^ "," Types ValueRef OptCAlign
+ | getresult Types ValueRef ^ "," EUINT64VAL
+ | getelementptr OptInBounds Types ValueRef IndexList
+ | extractvalue Types ValueRef ^ ConstantIndexList 
+ | insertvalue Types ValueRef ^ "," Types ValueRef ^ ConstantIndexList ;
diff --git a/src/LLVM/utils/llvmdo b/src/LLVM/utils/llvmdo
new file mode 100644
index 0000000..080208e
--- /dev/null
+++ b/src/LLVM/utils/llvmdo
@@ -0,0 +1,184 @@
+#!/bin/sh

+##===- utils/llvmdo - Counts Lines Of Code -------------------*- Script -*-===##

+# 

+#                     The LLVM Compiler Infrastructure

+#

+# This file is distributed under the University of Illinois Open Source

+# License. See LICENSE.TXT for details.

+# 

+##===----------------------------------------------------------------------===##

+#

+# This script is a general purpose "apply" function for the source files in LLVM

+# It uses "find" to locate all the source files and then applies the user's 

+# command to them. As such, this command is often not used by itself much but

+# the other find related tools (countloc.sh,llvmgrep,getsrcs.sh,userloc.sh) are

+# all based on this script.  This script defines "what is a source file" in 

+# LLVM and so should be maintained if new directories, new file extensions, 

+# etc. are used in LLVM as it progresses.

+#

+# Usage:

+#  llvmdo [-topdir DIR] [-dirs "DIRNAMES..."] [-code-only] PROGRAM ARGS...

+#

+# The -topdir option allows you to specify the llvm source root directly. If it

+# is not specified then it will be obtained with llvm-config which must be built

+# and in your path.

+#

+# The -dirs argument allows you to specify the set of directories that are 

+# searched. The default list of directories searched is:

+#   include lib tools utils runtime autoconf docs test examples projects

+# Note that you must use quotes around the list of directory names. 

+#

+# The -code-only option specifies that only those files that are considered 

+# "code" should be visited. HTML documentation is considered code, but things 

+# like README files, etc. are not.

+#

+# Finally, you simply specify whatever program you want to run against each 

+# file and the arguments to give it. The PROGRAM will be given the file name 

+# as its last argument.

+##===----------------------------------------------------------------------===##

+

+if test $# -lt 1 ; then

+  echo "Usage: llvmdo [-topdir DIR] [-dirs "DIRNAMES..."] [-code-only] PROGRAM ARGS..."

+  exit 1

+fi

+

+if test "$1" = "-topdir" ; then

+  TOPDIR="$2"

+  shift; shift;

+else

+  TOPDIR=`llvm-config --src-root`

+fi

+

+if test "$1" = "-dirs" ; then

+  LLVMDO_DIRS="$2"

+  shift ; shift

+elif test -z "$LLVMDO_DIRS" ; then

+  LLVMDO_DIRS="include lib tools utils runtime autoconf docs test examples projects cmake"

+fi

+

+if test "$1" = "-code-only" ; then

+  CODE_ONLY="set"

+  shift

+else

+  CODE_ONLY=""

+fi

+

+if test "$1" = "" ; then

+  echo "Missing program name to run"

+  exit 1

+fi

+

+PROGRAM=`which $1`

+if test ! -x "$PROGRAM" ; then

+  echo "Can't execute $1"

+  exit 1

+fi

+shift;

+

+paths_to_ignore="\

+  -path */.svn/ -o \

+  -path */.svn/* -o \

+  -path docs/doxygen/* -o \

+  -path docs/CommandGuide/html/* -o \

+  -path docs/CommandGuide/man/* -o \

+  -path docs/CommandGuide/ps/* -o \

+  -path docs/CommandGuide/man/* -o \

+  -path docs/HistoricalNotes/* -o \

+  -path docs/img/* -o \

+  -path */.libs/* -o \

+  -path lib/Support/bzip2/* -o \

+  -path projects/llvm-test/* \

+"

+files_to_match="\

+     -name *.ac \

+  -o -name *.b \

+  -o -name *.c \

+  -o -name *.cc \

+  -o -name *.cfg \

+  -o -name *.cpp \

+  -o -name *.css \

+  -o -name *.def \

+  -o -name *.el \

+  -o -name *.exp \

+  -o -name *.footer \

+  -o -name *.gnuplot' \

+  -o -name *.h \

+  -o -name *.header \

+  -o -name *.html \

+  -o -name *.in \

+  -o -name *.inc \

+  -o -name *.intro \

+  -o -name *.l \

+  -o -name *.ll \

+  -o -name *.lst \

+  -o -name *.m4 \

+  -o -name *.pod \

+  -o -name *.pl \

+  -o -name *.py \

+  -o -name *.sh \

+  -o -name *.schema \

+  -o -name *.st \

+  -o -name *.tcl \

+  -o -name *.td \

+  -o -name *.tr \

+  -o -name *.y \

+  -o -name Make* \

+  -o -name *.cmake \

+  -o -name llvmdo \

+  -o -name llvmgrep \

+  -o -name check-each-file \

+  -o -name codgen-diff \

+  -o -name llvm-native-gcc \

+  -o -name llvm-native-gxx \

+  -o -name makellvm \

+  -o -path include/llvm/ADT/ilist \

+  -o -path test/\*.ll \

+  -o -path test/Scripts/not \

+  -o -path runtime/\*.ll \

+"

+if test -z "$CODE_ONLY" ; then

+  files_to_match="$files_to_match \

+    -o -name *.txt \

+    -o -name *.TXT \

+    -o -name *.vim \

+    -o -name vimrc \

+    -o -name README \

+    -o -name COPYING.LIB \

+    -o -name LICENSE* "

+fi

+files_to_ignore="\

+     -name \.* \

+  -o -name *~ \

+  -o -name #* \

+  -o -name configure \

+  -o -name slow.ll \

+  -o -name *libtool* \

+  -o -name ltdl* \

+  -o -name ltdl.m4 \

+  -o -name ltmain.m4 \

+  -o -name ltmain.sh \

+  -o -name aclocal.m4 \

+  -o -name acinclude.m4 \

+  -o -name *LoopSimplifyCrash.ll \

+  -o -name *AST-Remove.ll \

+  -o -name PPCPerfectShuffle.h \

+"

+

+if test -d "$TOPDIR" ; then

+  cd $TOPDIR

+  # Have to use the right "find" on a per-platform basis. Most platforms have

+  # Gnu find as "find", but Solaris does not.

+  case `uname -s` in

+    SunOS) find_prog=gfind ;;

+    *) find_prog=find ;;

+  esac

+  # Turn off file name generation (globbing) so that substitution of the

+  # variables doesn't cause the shell to create lists of file names

+  set -f

+  $find_prog $LLVMDO_DIRS -type f \

+    \( $paths_to_ignore \) -prune \

+    -o \( \( $files_to_match \) \! \( $files_to_ignore \) \

+    -exec $PROGRAM "$@" {} \; \)

+else

+  echo "Can't find LLVM top directory in $TOPDIR"

+fi

diff --git a/src/LLVM/utils/llvmgrep b/src/LLVM/utils/llvmgrep
new file mode 100644
index 0000000..680e8a2
--- /dev/null
+++ b/src/LLVM/utils/llvmgrep
@@ -0,0 +1,39 @@
+#!/bin/sh

+##===- utils/llvmgrep - Counts Lines Of Code -----------------*- Script -*-===##

+# 

+#                     The LLVM Compiler Infrastructure

+#

+# This file is distributed under the University of Illinois Open Source

+# License. See LICENSE.TXT for details.

+# 

+##===----------------------------------------------------------------------===##

+#

+# This script searches your srcdir for an egrep style pattern. This can quickly

+# help you build a list of the places you need to modify when changing a header

+# or other "global" name. The only argument is the pattern you want to search

+# for. It should be quoted to escape shell interpretation of the pattern's

+# special characters.

+#

+# Note that the implementation is based on llvmdo. See that script for more

+# details.

+##===----------------------------------------------------------------------===##

+

+if test "$1" = "-topdir" ; then

+  TOPDIR="$2"

+  shift; shift;

+else

+  TOPDIR=`llvm-config --src-root`

+fi

+

+if test -d "$TOPDIR" ; then

+  cd $TOPDIR

+  case `uname -s` in

+    SunOS) grep_cmd="ggrep -H -n" ;;

+    Linux) grep_cmd="egrep -H -n" ;;

+    *) grep_cmd="egrep -l -n" ;;

+  esac

+  ./utils/llvmdo -topdir "$TOPDIR" \

+    -dirs "include lib tools utils docs examples test unittests projects cmake" $grep_cmd "$*"

+else

+  echo "Can't find LLVM top directory"

+fi

diff --git a/src/LLVM/utils/makellvm b/src/LLVM/utils/makellvm
new file mode 100644
index 0000000..5221cf5
--- /dev/null
+++ b/src/LLVM/utils/makellvm
@@ -0,0 +1,145 @@
+#!/bin/csh -f

+

+set pstatus = 0

+onintr cleanup

+alias usage 'echo "USAGE: $0:t [-h] [-n] [-obj obj-root] [gmake-flags] [VAR=...] [toolname (default: opt)]"; set pstatus = 1; goto cleanup'

+

+set EXEC = opt

+set GMAKE_OPTS = ""

+set DEBUG = 0

+

+## Search path for automatically finding the obj-root to use.

+## Note: The src root directory ${LLVMDIR} will be prepended to this path later.

+## 

+set OBJROOTDIRLIST = ( )

+

+set doit = 1

+unset options_done

+while ( !( $?options_done ) && ($#argv > 0))

+    switch ($argv[1])

+	case -h :

+	    usage

+	case -f :

+	    if ($#argv < 2) usage

+	    shift argv; set MFILE = $argv[1]; shift argv; breaksw

+	case -n :

+	    set doit = 0; shift argv; breaksw

+	case -obj :

+	    set OBJROOT = $argv[2]; shift argv; shift argv

+	    if (! -d "$OBJROOT") then

+		echo "FATAL: Illegal obj-root directory ${OBJROOT}"

+		exit 1

+	    endif

+	    breaksw

+	case -d :

+	    set doit = 0; set DEBUG = 1; shift argv; breaksw

+	case -* :

+	    set GMAKE_OPTS = ( $GMAKE_OPTS $argv[1] ); shift argv; breaksw

+	default :

+	    set optarg = `echo -n $argv[1] | sed 's/^[^=]*$//'`

+	    if ($#optarg) then

+	        set GMAKE_OPTS = ( $GMAKE_OPTS $optarg )

+	        shift argv

+	    else

+	        set options_done

+	    endif

+            breaksw

+    endsw

+end

+

+if ($#argv > 1) then

+    echo 'ERROR: More than one tool is not supported by "makellvm"'

+    usage

+endif

+if ($#argv > 0) then

+    set EXEC = $argv[1]

+endif

+if ($DEBUG) then

+    echo "DEBUG: EXEC = $EXEC"

+endif

+

+## Compute LLVMDIR: the root of the current LLVM tree.

+## It is recorded in the variable LEVEL in Makefile, to compute it

+## 

+if (! $?MFILE) then

+    if (-f GNUmakefile) then

+	set MFILE = GNUmakefile

+    else if (-f makefile) then

+	set MFILE = makefile

+    else

+	set MFILE = Makefile

+    endif

+endif

+if ($DEBUG) then

+    echo "DEBUG: MFILE = $MFILE"

+endif

+if (! -f $MFILE) then

+    echo "Missing or invalid makefile: $MFILE"

+    exit 1

+endif

+

+set LLVMDIR = `awk '/LEVEL[ 	]*=/ {print $NF}' $MFILE`

+if ($DEBUG) then

+    echo "DEBUG: LLVMDIR = $LLVMDIR"

+endif

+

+if ($#LLVMDIR == 0 || ! -d "$LLVMDIR") then

+    echo "Unable to find LLVM src-root directory or directory is invalid."

+    echo "Are you within a valid LLVM directory for running gmake?"

+    exit 1

+endif

+

+## Try to determine the obj-root directory automatically if not specified

+## 

+set OBJROOTDIRLIST = ( ${LLVMDIR} $OBJROOTDIRLIST )	## add src dir

+if ($?OBJROOT == 0) then

+    ## Try to determine object root directory by looking for Makefile.config

+    foreach objdir ( $OBJROOTDIRLIST )

+	if (-f "${objdir}/Makefile.config") then

+	    set OBJROOT = ${objdir}

+            break

+        endif

+    end

+    if ($?OBJROOT == 0) then

+	echo "FATAL: Could not choose an obj-root directory from these choices:"

+	echo "       ${OBJROOTDIRLIST}."

+	echo "       You can specify it explicitly using '-obj obj-root'."

+	exit 1

+    endif

+    echo "Using OBJ-ROOT = ${OBJROOT} (specify '-obj obj-root' to override)."

+endif

+if (${OBJROOT} == ${LLVMDIR}) then

+    # run make in the source directory itself

+    set BUILDROOT = .

+else

+    # run make in the in the obj-root tree, in the directory for $cwd

+    set SRCROOT = `sh -c "cd $LLVMDIR; pwd | sed 's/\//\\\//g'"` 

+    set CURSRCDIR = `echo $cwd | sed -e "s/${SRCROOT}//"`

+    set BUILDROOT = ${OBJROOT}/${CURSRCDIR}

+    unset SRCROOT CURSRCDIR

+endif

+if ($DEBUG) then

+    echo "DEBUG: BUILDROOT = $BUILDROOT"

+endif

+if (! -d $BUILDROOT) then

+    echo "FATAL: Invalid build directory: ${BUILDROOT}"

+    exit 1

+endif

+cd $BUILDROOT 

+

+set CMD = "make $GMAKE_OPTS && (cd $LLVMDIR/tools/$EXEC && make $GMAKE_OPTS)"

+

+if ($doit == 1) then

+    csh -f -c "$CMD"

+    set pstatus = $?

+else

+    echo '(NOT EXECUTING) COMMAND:'

+    echo "  $CMD"

+endif

+

+

+#=========================================================

+# CODE TO BE EXECUTED IF INTERRUPT IS RECEIVED

+#=========================================================

+cleanup:

+    exit($pstatus)

diff --git a/src/LLVM/utils/mkpatch b/src/LLVM/utils/mkpatch
new file mode 100644
index 0000000..955dbb7
--- /dev/null
+++ b/src/LLVM/utils/mkpatch
@@ -0,0 +1,37 @@
+#!/bin/bash

+#

+# This script makes a patch for LLVM ensuring the correct diff options and

+# putting the files in a standard review order.

+

+

+function error {

+  retcode="$?"

+  echo "mkpatch: error: $1 ($retcode)"

+  exit 1

+}

+

+if [ ! -e llvm.spec.in ] ; then

+  error "Please change directory to the LLVM top source directory"

+fi

+if [ "$#" -ne 1 ] ; then

+  error "usage: utils/mkpatch [PATCH_NAME]"

+fi

+NAME="$1"

+echo "mkpatch: Generating differences on top level files"

+svn diff -N -x -u > "$NAME".patch.raw 2>&1

+echo "mkpatch: Generating differences on all directories"

+svn diff -x -u  >> "$NAME".patch.raw 2>&1 \

+  autoconf docs utils include lib/System lib/Support lib/VMCore lib/AsmParser \

+  lib/Bitcode lib/Analysis lib/Transforms lib/CodeGen lib/Target \

+  lib/ExecutionEngine lib/Linker \

+  tools test unittests runtime projects examples Xcode

+

+echo "mkpatch: Removing cruft from the patch file"

+sed -e '/^[?] .*/d' -e '/^cvs diff: Diffing/d' "$NAME".patch.raw | awk '\

+BEGIN { deleting = 0; } \

+/^Index: .*[.]cvs$/ { deleting = 1; fname=substr($0,7); \

+  print "Skipping: ", fname > "/dev/stderr"; } \

+/^Index:.*/ && !/^Index: .*[.]cvs$/ { deleting = 0; } \

+{ if (! deleting) { print; } } '  > "$NAME".patch  || \

+  error "sed/awk cleanup failed"

+

diff --git a/src/LLVM/utils/not/CMakeLists.txt b/src/LLVM/utils/not/CMakeLists.txt
new file mode 100644
index 0000000..407c82e
--- /dev/null
+++ b/src/LLVM/utils/not/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_executable(not
+  not.cpp
+  )
+
+target_link_libraries(not LLVMSystem)
+if( MINGW )
+  target_link_libraries(not imagehlp psapi)
+endif( MINGW )
+if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD )
+  target_link_libraries(not pthread)
+endif()
diff --git a/src/LLVM/utils/not/Makefile b/src/LLVM/utils/not/Makefile
new file mode 100644
index 0000000..fef4802
--- /dev/null
+++ b/src/LLVM/utils/not/Makefile
@@ -0,0 +1,21 @@
+##===- utils/not/Makefile ----------------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+TOOLNAME = not
+USEDLIBS = LLVMSupport.a LLVMSystem.a
+
+# This tool has no plugins, optimize startup time.
+TOOL_NO_EXPORTS = 1
+
+# Don't install this utility
+NO_INSTALL = 1
+
+include $(LEVEL)/Makefile.common
+
diff --git a/src/LLVM/utils/not/not.cpp b/src/LLVM/utils/not/not.cpp
new file mode 100644
index 0000000..dd89b8f
--- /dev/null
+++ b/src/LLVM/utils/not/not.cpp
@@ -0,0 +1,17 @@
+//===- not.cpp - The 'not' testing tool -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/System/Path.h"
+#include "llvm/System/Program.h"
+using namespace llvm;
+
+int main(int argc, const char **argv) {
+  sys::Path Program = sys::Program::FindProgramByName(argv[1]);
+  return !sys::Program::ExecuteAndWait(Program, argv + 1);
+}
diff --git a/src/LLVM/utils/parseNLT.pl b/src/LLVM/utils/parseNLT.pl
new file mode 100644
index 0000000..95afca7
--- /dev/null
+++ b/src/LLVM/utils/parseNLT.pl
@@ -0,0 +1,34 @@
+#!/usr/bin/perl
+# a first attempt to parse the nightly tester pages into something
+# one can reason about, namely import into a database
+# USE: perl parseNLT.pl <2005-03-31.html
+# for example
+
+while(<>)
+  {
+    if (/LLVM Test Results for (\w+) (\d+), (\d+)</)
+      {
+        $mon = $1;
+        $day = $2;
+        $year = $3;
+      }
+    if (/<td>([^<]+)<\/td>/)
+      {
+        if ($prefix)
+          { $output .= "$1 "; $count++; }
+      }
+    if (/<tr/)
+      {
+        if ($output and $count > 3)
+          { print "\n$day $mon $year $prefix/$output"; }
+	$output = "";
+	$count = 0;
+      }
+    if (/<h2>(Programs.+)<\/h2>/)
+      {
+        $prefix = $1;
+      }
+  }
+
+if ($output)
+  { print "\n$day $mon $year $prefix/$output"; $output = ""; }
diff --git a/src/LLVM/utils/plotNLT.pl b/src/LLVM/utils/plotNLT.pl
new file mode 100644
index 0000000..55d503d
--- /dev/null
+++ b/src/LLVM/utils/plotNLT.pl
@@ -0,0 +1,53 @@
+#!/usr/bin/perl
+#takes a test and a program from a dp and produces a gnuplot script
+#use like perl plotNLT.pl password Programs/MultiSource/Benchmarks/ASCI_Purple/SMG2000/smg2000 llc
+
+use DBI;
+
+# database information
+$db="llvmalpha";
+$host="localhost";
+$userid="llvmdbuser";
+$passwd=shift @ARGV;
+$connectionInfo="dbi:mysql:$db;$host";
+
+# make connection to database
+$dbh = DBI->connect($connectionInfo,$userid,$passwd) or die DBI->errstr;
+
+
+$count = @ARGV / 2;
+
+print "set xdata time\n";
+print 'set timefmt "%Y-%m-%d"';
+print "\nplot";
+for ($iter = 0; $iter < $count; $iter++) {
+  if ($iter)
+    { print ","; }
+  print " '-' using 1:2 with lines";
+}
+
+print "\n";
+
+for ($iter = 0; $iter < $count; $iter++) {
+
+  $prog = shift @ARGV;
+  $test = shift @ARGV;
+
+  $query = "Select RUN, VALUE from Tests where TEST = '$test' AND NAME = '$prog' ORDER BY RUN";
+  #print "\n$query\n";
+  
+  my $sth = $dbh->prepare( $query) || die "Can't prepare statement: $DBI::errstr";;
+  
+  my $rc = $sth->execute or die DBI->errstr;
+  
+  while(($da,$v) = $sth->fetchrow_array)
+    {
+      print "$da $v\n";
+    }
+  
+  print "e\n";
+}
+
+
+# disconnect from database
+$dbh->disconnect;
diff --git a/src/LLVM/utils/profile.pl b/src/LLVM/utils/profile.pl
new file mode 100644
index 0000000..f9950f9
--- /dev/null
+++ b/src/LLVM/utils/profile.pl
@@ -0,0 +1,74 @@
+#!/usr/bin/perl -w
+#
+# Program:  profile.pl
+#
+# Synopsis: Insert instrumentation code into a program, run it with the JIT,
+#           then print out a profile report.
+#
+# Syntax:   profile.pl [OPTIONS] bytecodefile <arguments>
+#
+# OPTIONS may include one or more of the following:
+#     -block    - Enable basicblock profiling
+#     -edge     - Enable edge profiling
+#     -function - Enable function profiling
+#     -o <filename> - Emit profiling information to the specified file, instead
+#                     of llvmprof.out
+#
+# Any unrecognized options are passed into the invocation of llvm-prof
+#
+
+my $ProfilePass = "-insert-edge-profiling";
+
+my $LLVMProfOpts = "";
+my $ProgramOpts = "";
+my $ProfileFile = "";
+
+# Parse arguments...
+while (scalar(@ARGV) and ($_ = $ARGV[0], /^[-+]/)) {
+  shift;
+  last if /^--$/;  # Stop processing arguments on --
+
+  # List command line options here...
+  if (/^-?-block$/)    { $ProfilePass = "-insert-block-profiling"; next; }
+  if (/^-?-edge$/)     { $ProfilePass = "-insert-edge-profiling"; next; }
+  if (/^-?-function$/) { $ProfilePass = "-insert-function-profiling"; next; }
+  if (/^-?-o$/) {         # Read -o filename...
+    die "-o option requires a filename argument!" if (!scalar(@ARGV));
+    $ProgramOpts .= " -llvmprof-output $ARGV[0]";
+    $ProfileFile = $ARGV[0];
+    shift;
+    next;
+  }
+  if (/^-?-help$/) {
+    print "OVERVIEW: profile.pl - Instrumentation and profile printer.\n\n";
+    print "USAGE: profile.pl [options] program.bc <program args>\n\n";
+    print "OPTIONS:\n";
+    print "  -block    - Enable basicblock profiling\n";
+    print "  -edge     - Enable edge profiling\n";
+    print "  -function - Enable function profiling\n";
+    print "  -o <file> - Specify an output file other than llvm-prof.out.\n";
+    print "  -help     - Print this usage information\n";
+    print "\nAll other options are passed into llvm-prof.\n";
+    exit 1;
+  }
+
+  # Otherwise, pass the option on to llvm-prof
+  $LLVMProfOpts .= " " . $_;
+}
+
+die "Must specify LLVM bytecode file as first argument!" if (@ARGV == 0);
+
+my $BytecodeFile = $ARGV[0];
+
+shift @ARGV;
+
+my $libdir = `llvm-config --libdir`;
+chomp $libdir;
+
+my $LibProfPath = $libdir . "/profile_rt.so";
+
+system "opt -q -f $ProfilePass $BytecodeFile -o $BytecodeFile.inst";
+system "lli -fake-argv0 '$BytecodeFile' -load $LibProfPath " .
+       "$BytecodeFile.inst $ProgramOpts " . (join ' ', @ARGV);
+system "rm $BytecodeFile.inst";
+system "llvm-prof $LLVMProfOpts $BytecodeFile $ProfileFile";
diff --git a/src/LLVM/utils/unittest/Makefile b/src/LLVM/utils/unittest/Makefile
new file mode 100644
index 0000000..6a09341
--- /dev/null
+++ b/src/LLVM/utils/unittest/Makefile
@@ -0,0 +1,13 @@
+##===- utils/unittest/Makefile -----------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+PARALLEL_DIRS = googletest UnitTestMain
+
+include $(LEVEL)/Makefile.common
diff --git a/src/LLVM/utils/unittest/UnitTestMain/Makefile b/src/LLVM/utils/unittest/UnitTestMain/Makefile
new file mode 100644
index 0000000..cec654f
--- /dev/null
+++ b/src/LLVM/utils/unittest/UnitTestMain/Makefile
@@ -0,0 +1,30 @@
+##===- utils/unittest/UnitTestMain/Makefile ----------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../..
+
+include $(LEVEL)/Makefile.config
+
+LIBRARYNAME = UnitTestMain
+BUILD_ARCHIVE = 1
+REQUIRES_RTTI = 1
+
+CPP.Flags += -I$(LLVM_SRC_ROOT)/utils/unittest/googletest/include
+CPP.Flags += $(NO_MISSING_FIELD_INITIALIZERS) $(NO_VARIADIC_MACROS)
+CPP.Flags += -DGTEST_HAS_RTTI=0
+# libstdc++'s TR1 <tuple> header depends on RTTI and uses C++'0x features not
+# supported by Clang, so force googletest to use its own tuple implementation.
+CPP.Flags += -DGTEST_USE_OWN_TR1_TUPLE
+
+# Disable pthreads if LLVM was configured without them.
+ifneq ($(HAVE_PTHREAD), 1)
+  CPP.Flags += -DGTEST_HAS_PTHREAD=0
+endif
+
+include $(LEVEL)/Makefile.common
diff --git a/src/LLVM/utils/unittest/UnitTestMain/TestMain.cpp b/src/LLVM/utils/unittest/UnitTestMain/TestMain.cpp
new file mode 100644
index 0000000..d97dca8
--- /dev/null
+++ b/src/LLVM/utils/unittest/UnitTestMain/TestMain.cpp
@@ -0,0 +1,15 @@
+//===--- utils/unittest/UnitTestMain/TestMain.cpp - unittest driver -------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+
+int main(int argc, char **argv) {
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/src/LLVM/utils/unittest/googletest/LICENSE.TXT b/src/LLVM/utils/unittest/googletest/LICENSE.TXT
new file mode 100644
index 0000000..1941a11
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/LICENSE.TXT
@@ -0,0 +1,28 @@
+Copyright 2008, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+    * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/LLVM/utils/unittest/googletest/Makefile b/src/LLVM/utils/unittest/googletest/Makefile
new file mode 100644
index 0000000..21b29ff
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/Makefile
@@ -0,0 +1,39 @@
+##===- utils/unittest/googletest/Makefile ------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL := ../../..
+
+include $(LEVEL)/Makefile.config
+
+LIBRARYNAME = GoogleTest
+BUILD_ARCHIVE = 1
+REQUIRES_RTTI = 1
+
+# Note that these flags are duplicated when building individual tests in
+# unittests/Makefile.unittest and ../UnitTestMain/Makefile; ensure that any
+# changes are made to both.
+CPP.Flags += -I$(LLVM_SRC_ROOT)/utils/unittest/googletest/include
+CPP.Flags += $(NO_MISSING_FIELD_INITIALIZERS) $(NO_VARIADIC_MACROS)
+CPP.Flags += -DGTEST_HAS_RTTI=0
+# libstdc++'s TR1 <tuple> header depends on RTTI and uses C++'0x features not
+# supported by Clang, so force googletest to use its own tuple implementation.
+CPP.Flags += -DGTEST_USE_OWN_TR1_TUPLE
+
+# Disable pthreads if LLVM was configured without them.
+ifneq ($(HAVE_PTHREAD), 1)
+  CPP.Flags += -DGTEST_HAS_PTHREAD=0
+endif
+
+ifeq ($(HOST_OS),MingW)
+  CPP.Flags += -DGTEST_OS_WINDOWS=1
+endif
+
+NO_INSTALL = 1
+
+include $(LEVEL)/Makefile.common
diff --git a/src/LLVM/utils/unittest/googletest/README.LLVM b/src/LLVM/utils/unittest/googletest/README.LLVM
new file mode 100644
index 0000000..d6e6f98
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/README.LLVM
@@ -0,0 +1,31 @@
+LLVM notes
+----------
+
+This directory contains Google Test 1.5.0, with all elements removed except for
+the actual source code, to minimize the addition to the LLVM distribution.
+
+Cleaned up as follows:
+
+# Remove all the unnecessary files and directories
+$ rm -f aclocal* CMakeLists.txt configure* Makefile* CHANGES CONTRIBUTORS README
+$ rm -rf build-aux codegear fused-src m4 make msvc samples scripts test xcode
+$ rm -f `find . -name \*\.pump`
+
+# Move all the source files to the current directory
+$ mv src/* .
+$ rmdir src
+
+# Move extra headers into the already-existing internal headers dir
+$ mv *.h include/gtest/internal/
+
+# Update paths to the included files
+$ perl -pi -e 's|^#include "src/|#include "gtest/internal/|' *.cc
+
+$ mv COPYING LICENSE.TXT
+
+
+Modified as follows:
+* To GTestStreamToHelper in include/gtest/internal/gtest-internal.h,
+  added the ability to stream with raw_os_ostream.
+* To refresh Haiku support in include/gtest/internal/gtest-port.h,
+  see http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20100621/102898.html
diff --git a/src/LLVM/utils/unittest/googletest/gtest-death-test.cc b/src/LLVM/utils/unittest/googletest/gtest-death-test.cc
new file mode 100644
index 0000000..e4199de
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/gtest-death-test.cc
@@ -0,0 +1,1172 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev)
+//
+// This file implements death tests.
+
+#include <gtest/gtest-death-test.h>
+#include <gtest/internal/gtest-port.h>
+
+#if GTEST_HAS_DEATH_TEST
+
+#if GTEST_OS_MAC
+#include <crt_externs.h>
+#endif  // GTEST_OS_MAC
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdarg.h>
+
+#if GTEST_OS_WINDOWS
+#include <windows.h>
+#else
+#include <sys/mman.h>
+#include <sys/wait.h>
+#endif  // GTEST_OS_WINDOWS
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+#include <gtest/gtest-message.h>
+#include <gtest/internal/gtest-string.h>
+
+// Indicates that this translation unit is part of Google Test's
+// implementation.  It must come before gtest-internal-inl.h is
+// included, or there will be a compiler error.  This trick is to
+// prevent a user from accidentally including gtest-internal-inl.h in
+// his code.
+#define GTEST_IMPLEMENTATION_ 1
+#include "gtest/internal/gtest-internal-inl.h"
+#undef GTEST_IMPLEMENTATION_
+
+namespace testing {
+
+// Constants.
+
+// The default death test style.
+static const char kDefaultDeathTestStyle[] = "fast";
+
+GTEST_DEFINE_string_(
+    death_test_style,
+    internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle),
+    "Indicates how to run a death test in a forked child process: "
+    "\"threadsafe\" (child process re-executes the test binary "
+    "from the beginning, running only the specific death test) or "
+    "\"fast\" (child process runs the death test immediately "
+    "after forking).");
+
+GTEST_DEFINE_bool_(
+    death_test_use_fork,
+    internal::BoolFromGTestEnv("death_test_use_fork", false),
+    "Instructs to use fork()/_exit() instead of clone() in death tests. "
+    "Ignored and always uses fork() on POSIX systems where clone() is not "
+    "implemented. Useful when running under valgrind or similar tools if "
+    "those do not support clone(). Valgrind 3.3.1 will just fail if "
+    "it sees an unsupported combination of clone() flags. "
+    "It is not recommended to use this flag w/o valgrind though it will "
+    "work in 99% of the cases. Once valgrind is fixed, this flag will "
+    "most likely be removed.");
+
+namespace internal {
+GTEST_DEFINE_string_(
+    internal_run_death_test, "",
+    "Indicates the file, line number, temporal index of "
+    "the single death test to run, and a file descriptor to "
+    "which a success code may be sent, all separated by "
+    "colons.  This flag is specified if and only if the current "
+    "process is a sub-process launched for running a thread-safe "
+    "death test.  FOR INTERNAL USE ONLY.");
+}  // namespace internal
+
+#if GTEST_HAS_DEATH_TEST
+
+// ExitedWithCode constructor.
+ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) {
+}
+
+// ExitedWithCode function-call operator.
+bool ExitedWithCode::operator()(int exit_status) const {
+#if GTEST_OS_WINDOWS
+  return exit_status == exit_code_;
+#else
+  return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_;
+#endif  // GTEST_OS_WINDOWS
+}
+
+#if !GTEST_OS_WINDOWS
+// KilledBySignal constructor.
+KilledBySignal::KilledBySignal(int signum) : signum_(signum) {
+}
+
+// KilledBySignal function-call operator.
+bool KilledBySignal::operator()(int exit_status) const {
+  return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_;
+}
+#endif  // !GTEST_OS_WINDOWS
+
+namespace internal {
+
+// Utilities needed for death tests.
+
+// Generates a textual description of a given exit code, in the format
+// specified by wait(2).
+static String ExitSummary(int exit_code) {
+  Message m;
+#if GTEST_OS_WINDOWS
+  m << "Exited with exit status " << exit_code;
+#else
+  if (WIFEXITED(exit_code)) {
+    m << "Exited with exit status " << WEXITSTATUS(exit_code);
+  } else if (WIFSIGNALED(exit_code)) {
+    m << "Terminated by signal " << WTERMSIG(exit_code);
+  }
+#ifdef WCOREDUMP
+  if (WCOREDUMP(exit_code)) {
+    m << " (core dumped)";
+  }
+#endif
+#endif  // GTEST_OS_WINDOWS
+  return m.GetString();
+}
+
+// Returns true if exit_status describes a process that was terminated
+// by a signal, or exited normally with a nonzero exit code.
+bool ExitedUnsuccessfully(int exit_status) {
+  return !ExitedWithCode(0)(exit_status);
+}
+
+#if !GTEST_OS_WINDOWS
+// Generates a textual failure message when a death test finds more than
+// one thread running, or cannot determine the number of threads, prior
+// to executing the given statement.  It is the responsibility of the
+// caller not to pass a thread_count of 1.
+static String DeathTestThreadWarning(size_t thread_count) {
+  Message msg;
+  msg << "Death tests use fork(), which is unsafe particularly"
+      << " in a threaded context. For this test, " << GTEST_NAME_ << " ";
+  if (thread_count == 0)
+    msg << "couldn't detect the number of threads.";
+  else
+    msg << "detected " << thread_count << " threads.";
+  return msg.GetString();
+}
+#endif  // !GTEST_OS_WINDOWS
+
+// Flag characters for reporting a death test that did not die.
+static const char kDeathTestLived = 'L';
+static const char kDeathTestReturned = 'R';
+static const char kDeathTestInternalError = 'I';
+
+// An enumeration describing all of the possible ways that a death test
+// can conclude.  DIED means that the process died while executing the
+// test code; LIVED means that process lived beyond the end of the test
+// code; and RETURNED means that the test statement attempted a "return,"
+// which is not allowed.  IN_PROGRESS means the test has not yet
+// concluded.
+enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED };
+
+// Routine for aborting the program which is safe to call from an
+// exec-style death test child process, in which case the error
+// message is propagated back to the parent process.  Otherwise, the
+// message is simply printed to stderr.  In either case, the program
+// then exits with status 1.
+void DeathTestAbort(const String& message) {
+  // On a POSIX system, this function may be called from a threadsafe-style
+  // death test child process, which operates on a very small stack.  Use
+  // the heap for any additional non-minuscule memory requirements.
+  const InternalRunDeathTestFlag* const flag =
+      GetUnitTestImpl()->internal_run_death_test_flag();
+  if (flag != NULL) {
+    FILE* parent = posix::FDOpen(flag->write_fd(), "w");
+    fputc(kDeathTestInternalError, parent);
+    fprintf(parent, "%s", message.c_str());
+    fflush(parent);
+    _exit(1);
+  } else {
+    fprintf(stderr, "%s", message.c_str());
+    fflush(stderr);
+    abort();
+  }
+}
+
+// A replacement for CHECK that calls DeathTestAbort if the assertion
+// fails.
+#define GTEST_DEATH_TEST_CHECK_(expression) \
+  do { \
+    if (!::testing::internal::IsTrue(expression)) { \
+      DeathTestAbort(::testing::internal::String::Format( \
+          "CHECK failed: File %s, line %d: %s", \
+          __FILE__, __LINE__, #expression)); \
+    } \
+  } while (::testing::internal::AlwaysFalse())
+
+// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for
+// evaluating any system call that fulfills two conditions: it must return
+// -1 on failure, and set errno to EINTR when it is interrupted and
+// should be tried again.  The macro expands to a loop that repeatedly
+// evaluates the expression as long as it evaluates to -1 and sets
+// errno to EINTR.  If the expression evaluates to -1 but errno is
+// something other than EINTR, DeathTestAbort is called.
+#define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \
+  do { \
+    int gtest_retval; \
+    do { \
+      gtest_retval = (expression); \
+    } while (gtest_retval == -1 && errno == EINTR); \
+    if (gtest_retval == -1) { \
+      DeathTestAbort(::testing::internal::String::Format( \
+          "CHECK failed: File %s, line %d: %s != -1", \
+          __FILE__, __LINE__, #expression)); \
+    } \
+  } while (::testing::internal::AlwaysFalse())
+
+// Returns the message describing the last system error in errno.
+String GetLastErrnoDescription() {
+    return String(errno == 0 ? "" : posix::StrError(errno));
+}
+
+// This is called from a death test parent process to read a failure
+// message from the death test child process and log it with the FATAL
+// severity. On Windows, the message is read from a pipe handle. On other
+// platforms, it is read from a file descriptor.
+static void FailFromInternalError(int fd) {
+  Message error;
+  char buffer[256];
+  int num_read;
+
+  do {
+    while ((num_read = posix::Read(fd, buffer, 255)) > 0) {
+      buffer[num_read] = '\0';
+      error << buffer;
+    }
+  } while (num_read == -1 && errno == EINTR);
+
+  if (num_read == 0) {
+    GTEST_LOG_(FATAL) << error.GetString();
+  } else {
+    const int last_error = errno;
+    GTEST_LOG_(FATAL) << "Error while reading death test internal: "
+                      << GetLastErrnoDescription() << " [" << last_error << "]";
+  }
+}
+
+// Death test constructor.  Increments the running death test count
+// for the current test.
+DeathTest::DeathTest() {
+  TestInfo* const info = GetUnitTestImpl()->current_test_info();
+  if (info == NULL) {
+    DeathTestAbort("Cannot run a death test outside of a TEST or "
+                   "TEST_F construct");
+  }
+}
+
+// Creates and returns a death test by dispatching to the current
+// death test factory.
+bool DeathTest::Create(const char* statement, const RE* regex,
+                       const char* file, int line, DeathTest** test) {
+  return GetUnitTestImpl()->death_test_factory()->Create(
+      statement, regex, file, line, test);
+}
+
+const char* DeathTest::LastMessage() {
+  return last_death_test_message_.c_str();
+}
+
+void DeathTest::set_last_death_test_message(const String& message) {
+  last_death_test_message_ = message;
+}
+
+String DeathTest::last_death_test_message_;
+
+// Provides cross platform implementation for some death functionality.
+class DeathTestImpl : public DeathTest {
+ protected:
+  DeathTestImpl(const char* a_statement, const RE* a_regex)
+      : statement_(a_statement),
+        regex_(a_regex),
+        spawned_(false),
+        status_(-1),
+        outcome_(IN_PROGRESS),
+        read_fd_(-1),
+        write_fd_(-1) {}
+
+  // read_fd_ is expected to be closed and cleared by a derived class.
+  ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); }
+
+  void Abort(AbortReason reason);
+  virtual bool Passed(bool status_ok);
+
+  const char* statement() const { return statement_; }
+  const RE* regex() const { return regex_; }
+  bool spawned() const { return spawned_; }
+  void set_spawned(bool is_spawned) { spawned_ = is_spawned; }
+  int status() const { return status_; }
+  void set_status(int a_status) { status_ = a_status; }
+  DeathTestOutcome outcome() const { return outcome_; }
+  void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; }
+  int read_fd() const { return read_fd_; }
+  void set_read_fd(int fd) { read_fd_ = fd; }
+  int write_fd() const { return write_fd_; }
+  void set_write_fd(int fd) { write_fd_ = fd; }
+
+  // Called in the parent process only. Reads the result code of the death
+  // test child process via a pipe, interprets it to set the outcome_
+  // member, and closes read_fd_.  Outputs diagnostics and terminates in
+  // case of unexpected codes.
+  void ReadAndInterpretStatusByte();
+
+ private:
+  // The textual content of the code this object is testing.  This class
+  // doesn't own this string and should not attempt to delete it.
+  const char* const statement_;
+  // The regular expression which test output must match.  DeathTestImpl
+  // doesn't own this object and should not attempt to delete it.
+  const RE* const regex_;
+  // True if the death test child process has been successfully spawned.
+  bool spawned_;
+  // The exit status of the child process.
+  int status_;
+  // How the death test concluded.
+  DeathTestOutcome outcome_;
+  // Descriptor to the read end of the pipe to the child process.  It is
+  // always -1 in the child process.  The child keeps its write end of the
+  // pipe in write_fd_.
+  int read_fd_;
+  // Descriptor to the child's write end of the pipe to the parent process.
+  // It is always -1 in the parent process.  The parent keeps its end of the
+  // pipe in read_fd_.
+  int write_fd_;
+};
+
+// Called in the parent process only. Reads the result code of the death
+// test child process via a pipe, interprets it to set the outcome_
+// member, and closes read_fd_.  Outputs diagnostics and terminates in
+// case of unexpected codes.
+void DeathTestImpl::ReadAndInterpretStatusByte() {
+  char flag;
+  int bytes_read;
+
+  // The read() here blocks until data is available (signifying the
+  // failure of the death test) or until the pipe is closed (signifying
+  // its success), so it's okay to call this in the parent before
+  // the child process has exited.
+  do {
+    bytes_read = posix::Read(read_fd(), &flag, 1);
+  } while (bytes_read == -1 && errno == EINTR);
+
+  if (bytes_read == 0) {
+    set_outcome(DIED);
+  } else if (bytes_read == 1) {
+    switch (flag) {
+      case kDeathTestReturned:
+        set_outcome(RETURNED);
+        break;
+      case kDeathTestLived:
+        set_outcome(LIVED);
+        break;
+      case kDeathTestInternalError:
+        FailFromInternalError(read_fd());  // Does not return.
+        break;
+      default:
+        GTEST_LOG_(FATAL) << "Death test child process reported "
+                          << "unexpected status byte ("
+                          << static_cast<unsigned int>(flag) << ")";
+    }
+  } else {
+    GTEST_LOG_(FATAL) << "Read from death test child process failed: "
+                      << GetLastErrnoDescription();
+  }
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd()));
+  set_read_fd(-1);
+}
+
+// Signals that the death test code which should have exited, didn't.
+// Should be called only in a death test child process.
+// Writes a status byte to the child's status file descriptor, then
+// calls _exit(1).
+void DeathTestImpl::Abort(AbortReason reason) {
+  // The parent process considers the death test to be a failure if
+  // it finds any data in our pipe.  So, here we write a single flag byte
+  // to the pipe, then exit.
+  const char status_ch =
+      reason == TEST_DID_NOT_DIE ? kDeathTestLived : kDeathTestReturned;
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1));
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(write_fd()));
+  _exit(1);  // Exits w/o any normal exit hooks (we were supposed to crash)
+}
+
+// Assesses the success or failure of a death test, using both private
+// members which have previously been set, and one argument:
+//
+// Private data members:
+//   outcome:  An enumeration describing how the death test
+//             concluded: DIED, LIVED, or RETURNED.  The death test fails
+//             in the latter two cases.
+//   status:   The exit status of the child process. On *nix, it is in the
+//             in the format specified by wait(2). On Windows, this is the
+//             value supplied to the ExitProcess() API or a numeric code
+//             of the exception that terminated the program.
+//   regex:    A regular expression object to be applied to
+//             the test's captured standard error output; the death test
+//             fails if it does not match.
+//
+// Argument:
+//   status_ok: true if exit_status is acceptable in the context of
+//              this particular death test, which fails if it is false
+//
+// Returns true iff all of the above conditions are met.  Otherwise, the
+// first failing condition, in the order given above, is the one that is
+// reported. Also sets the last death test message string.
+bool DeathTestImpl::Passed(bool status_ok) {
+  if (!spawned())
+    return false;
+
+  const String error_message = GetCapturedStderr();
+
+  bool success = false;
+  Message buffer;
+
+  buffer << "Death test: " << statement() << "\n";
+  switch (outcome()) {
+    case LIVED:
+      buffer << "    Result: failed to die.\n"
+             << " Error msg: " << error_message;
+      break;
+    case RETURNED:
+      buffer << "    Result: illegal return in test statement.\n"
+             << " Error msg: " << error_message;
+      break;
+    case DIED:
+      if (status_ok) {
+        const bool matched = RE::PartialMatch(error_message.c_str(), *regex());
+        if (matched) {
+          success = true;
+        } else {
+          buffer << "    Result: died but not with expected error.\n"
+                 << "  Expected: " << regex()->pattern() << "\n"
+                 << "Actual msg: " << error_message;
+        }
+      } else {
+        buffer << "    Result: died but not with expected exit code:\n"
+               << "            " << ExitSummary(status()) << "\n";
+      }
+      break;
+    case IN_PROGRESS:
+    default:
+      GTEST_LOG_(FATAL)
+          << "DeathTest::Passed somehow called before conclusion of test";
+  }
+
+  DeathTest::set_last_death_test_message(buffer.GetString());
+  return success;
+}
+
+#if GTEST_OS_WINDOWS
+// WindowsDeathTest implements death tests on Windows. Due to the
+// specifics of starting new processes on Windows, death tests there are
+// always threadsafe, and Google Test considers the
+// --gtest_death_test_style=fast setting to be equivalent to
+// --gtest_death_test_style=threadsafe there.
+//
+// A few implementation notes:  Like the Linux version, the Windows
+// implementation uses pipes for child-to-parent communication. But due to
+// the specifics of pipes on Windows, some extra steps are required:
+//
+// 1. The parent creates a communication pipe and stores handles to both
+//    ends of it.
+// 2. The parent starts the child and provides it with the information
+//    necessary to acquire the handle to the write end of the pipe.
+// 3. The child acquires the write end of the pipe and signals the parent
+//    using a Windows event.
+// 4. Now the parent can release the write end of the pipe on its side. If
+//    this is done before step 3, the object's reference count goes down to
+//    0 and it is destroyed, preventing the child from acquiring it. The
+//    parent now has to release it, or read operations on the read end of
+//    the pipe will not return when the child terminates.
+// 5. The parent reads child's output through the pipe (outcome code and
+//    any possible error messages) from the pipe, and its stderr and then
+//    determines whether to fail the test.
+//
+// Note: to distinguish Win32 API calls from the local method and function
+// calls, the former are explicitly resolved in the global namespace.
+//
+class WindowsDeathTest : public DeathTestImpl {
+ public:
+  WindowsDeathTest(const char* statement,
+                   const RE* regex,
+                   const char* file,
+                   int line)
+      : DeathTestImpl(statement, regex), file_(file), line_(line) {}
+
+  // All of these virtual functions are inherited from DeathTest.
+  virtual int Wait();
+  virtual TestRole AssumeRole();
+
+ private:
+  // The name of the file in which the death test is located.
+  const char* const file_;
+  // The line number on which the death test is located.
+  const int line_;
+  // Handle to the write end of the pipe to the child process.
+  AutoHandle write_handle_;
+  // Child process handle.
+  AutoHandle child_handle_;
+  // Event the child process uses to signal the parent that it has
+  // acquired the handle to the write end of the pipe. After seeing this
+  // event the parent can release its own handles to make sure its
+  // ReadFile() calls return when the child terminates.
+  AutoHandle event_handle_;
+};
+
+// Waits for the child in a death test to exit, returning its exit
+// status, or 0 if no child process exists.  As a side effect, sets the
+// outcome data member.
+int WindowsDeathTest::Wait() {
+  if (!spawned())
+    return 0;
+
+  // Wait until the child either signals that it has acquired the write end
+  // of the pipe or it dies.
+  const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() };
+  switch (::WaitForMultipleObjects(2,
+                                   wait_handles,
+                                   FALSE,  // Waits for any of the handles.
+                                   INFINITE)) {
+    case WAIT_OBJECT_0:
+    case WAIT_OBJECT_0 + 1:
+      break;
+    default:
+      GTEST_DEATH_TEST_CHECK_(false);  // Should not get here.
+  }
+
+  // The child has acquired the write end of the pipe or exited.
+  // We release the handle on our side and continue.
+  write_handle_.Reset();
+  event_handle_.Reset();
+
+  ReadAndInterpretStatusByte();
+
+  // Waits for the child process to exit if it haven't already. This
+  // returns immediately if the child has already exited, regardless of
+  // whether previous calls to WaitForMultipleObjects synchronized on this
+  // handle or not.
+  GTEST_DEATH_TEST_CHECK_(
+      WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(),
+                                             INFINITE));
+  DWORD status;
+  GTEST_DEATH_TEST_CHECK_(::GetExitCodeProcess(child_handle_.Get(), &status)
+                          != FALSE);
+  child_handle_.Reset();
+  set_status(static_cast<int>(status));
+  return this->status();
+}
+
+// The AssumeRole process for a Windows death test.  It creates a child
+// process with the same executable as the current process to run the
+// death test.  The child process is given the --gtest_filter and
+// --gtest_internal_run_death_test flags such that it knows to run the
+// current death test only.
+DeathTest::TestRole WindowsDeathTest::AssumeRole() {
+  const UnitTestImpl* const impl = GetUnitTestImpl();
+  const InternalRunDeathTestFlag* const flag =
+      impl->internal_run_death_test_flag();
+  const TestInfo* const info = impl->current_test_info();
+  const int death_test_index = info->result()->death_test_count();
+
+  if (flag != NULL) {
+    // ParseInternalRunDeathTestFlag() has performed all the necessary
+    // processing.
+    set_write_fd(flag->write_fd());
+    return EXECUTE_TEST;
+  }
+
+  // WindowsDeathTest uses an anonymous pipe to communicate results of
+  // a death test.
+  SECURITY_ATTRIBUTES handles_are_inheritable = {
+    sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
+  HANDLE read_handle, write_handle;
+  GTEST_DEATH_TEST_CHECK_(
+      ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable,
+                   0)  // Default buffer size.
+      != FALSE);
+  set_read_fd(::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle),
+                                O_RDONLY));
+  write_handle_.Reset(write_handle);
+  event_handle_.Reset(::CreateEvent(
+      &handles_are_inheritable,
+      TRUE,    // The event will automatically reset to non-signaled state.
+      FALSE,   // The initial state is non-signalled.
+      NULL));  // The even is unnamed.
+  GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL);
+  const String filter_flag = String::Format("--%s%s=%s.%s",
+                                            GTEST_FLAG_PREFIX_, kFilterFlag,
+                                            info->test_case_name(),
+                                            info->name());
+  const String internal_flag = String::Format(
+    "--%s%s=%s|%d|%d|%u|%Iu|%Iu",
+      GTEST_FLAG_PREFIX_,
+      kInternalRunDeathTestFlag,
+      file_, line_,
+      death_test_index,
+      static_cast<unsigned int>(::GetCurrentProcessId()),
+      // size_t has the same with as pointers on both 32-bit and 64-bit
+      // Windows platforms.
+      // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.
+      reinterpret_cast<size_t>(write_handle),
+      reinterpret_cast<size_t>(event_handle_.Get()));
+
+  char executable_path[_MAX_PATH + 1];  // NOLINT
+  GTEST_DEATH_TEST_CHECK_(
+      _MAX_PATH + 1 != ::GetModuleFileNameA(NULL,
+                                            executable_path,
+                                            _MAX_PATH));
+
+  String command_line = String::Format("%s %s \"%s\"",
+                                       ::GetCommandLineA(),
+                                       filter_flag.c_str(),
+                                       internal_flag.c_str());
+
+  DeathTest::set_last_death_test_message("");
+
+  CaptureStderr();
+  // Flush the log buffers since the log streams are shared with the child.
+  FlushInfoLog();
+
+  // The child process will share the standard handles with the parent.
+  STARTUPINFOA startup_info;
+  memset(&startup_info, 0, sizeof(STARTUPINFO));
+  startup_info.dwFlags = STARTF_USESTDHANDLES;
+  startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE);
+  startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
+  startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
+
+  PROCESS_INFORMATION process_info;
+  GTEST_DEATH_TEST_CHECK_(::CreateProcessA(
+      executable_path,
+      const_cast<char*>(command_line.c_str()),
+      NULL,   // Retuned process handle is not inheritable.
+      NULL,   // Retuned thread handle is not inheritable.
+      TRUE,   // Child inherits all inheritable handles (for write_handle_).
+      0x0,    // Default creation flags.
+      NULL,   // Inherit the parent's environment.
+      UnitTest::GetInstance()->original_working_dir(),
+      &startup_info,
+      &process_info) != FALSE);
+  child_handle_.Reset(process_info.hProcess);
+  ::CloseHandle(process_info.hThread);
+  set_spawned(true);
+  return OVERSEE_TEST;
+}
+#else  // We are not on Windows.
+
+// ForkingDeathTest provides implementations for most of the abstract
+// methods of the DeathTest interface.  Only the AssumeRole method is
+// left undefined.
+class ForkingDeathTest : public DeathTestImpl {
+ public:
+  ForkingDeathTest(const char* statement, const RE* regex);
+
+  // All of these virtual functions are inherited from DeathTest.
+  virtual int Wait();
+
+ protected:
+  void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; }
+
+ private:
+  // PID of child process during death test; 0 in the child process itself.
+  pid_t child_pid_;
+};
+
+// Constructs a ForkingDeathTest.
+ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex)
+    : DeathTestImpl(a_statement, a_regex),
+      child_pid_(-1) {}
+
+// Waits for the child in a death test to exit, returning its exit
+// status, or 0 if no child process exists.  As a side effect, sets the
+// outcome data member.
+int ForkingDeathTest::Wait() {
+  if (!spawned())
+    return 0;
+
+  ReadAndInterpretStatusByte();
+
+  int status_value;
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0));
+  set_status(status_value);
+  return status_value;
+}
+
+// A concrete death test class that forks, then immediately runs the test
+// in the child process.
+class NoExecDeathTest : public ForkingDeathTest {
+ public:
+  NoExecDeathTest(const char* a_statement, const RE* a_regex) :
+      ForkingDeathTest(a_statement, a_regex) { }
+  virtual TestRole AssumeRole();
+};
+
+// The AssumeRole process for a fork-and-run death test.  It implements a
+// straightforward fork, with a simple pipe to transmit the status byte.
+DeathTest::TestRole NoExecDeathTest::AssumeRole() {
+  const size_t thread_count = GetThreadCount();
+  if (thread_count != 1) {
+    GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count);
+  }
+
+  int pipe_fd[2];
+  GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1);
+
+  DeathTest::set_last_death_test_message("");
+  CaptureStderr();
+  // When we fork the process below, the log file buffers are copied, but the
+  // file descriptors are shared.  We flush all log files here so that closing
+  // the file descriptors in the child process doesn't throw off the
+  // synchronization between descriptors and buffers in the parent process.
+  // This is as close to the fork as possible to avoid a race condition in case
+  // there are multiple threads running before the death test, and another
+  // thread writes to the log file.
+  FlushInfoLog();
+
+  const pid_t child_pid = fork();
+  GTEST_DEATH_TEST_CHECK_(child_pid != -1);
+  set_child_pid(child_pid);
+  if (child_pid == 0) {
+    GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0]));
+    set_write_fd(pipe_fd[1]);
+    // Redirects all logging to stderr in the child process to prevent
+    // concurrent writes to the log files.  We capture stderr in the parent
+    // process and append the child process' output to a log.
+    LogToStderr();
+    // Event forwarding to the listeners of event listener API mush be shut
+    // down in death test subprocesses.
+    GetUnitTestImpl()->listeners()->SuppressEventForwarding();
+    return EXECUTE_TEST;
+  } else {
+    GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
+    set_read_fd(pipe_fd[0]);
+    set_spawned(true);
+    return OVERSEE_TEST;
+  }
+}
+
+// A concrete death test class that forks and re-executes the main
+// program from the beginning, with command-line flags set that cause
+// only this specific death test to be run.
+class ExecDeathTest : public ForkingDeathTest {
+ public:
+  ExecDeathTest(const char* a_statement, const RE* a_regex,
+                const char* file, int line) :
+      ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { }
+  virtual TestRole AssumeRole();
+ private:
+  // The name of the file in which the death test is located.
+  const char* const file_;
+  // The line number on which the death test is located.
+  const int line_;
+};
+
+// Utility class for accumulating command-line arguments.
+class Arguments {
+ public:
+  Arguments() {
+    args_.push_back(NULL);
+  }
+
+  ~Arguments() {
+    for (std::vector<char*>::iterator i = args_.begin(); i != args_.end();
+         ++i) {
+      free(*i);
+    }
+  }
+  void AddArgument(const char* argument) {
+    args_.insert(args_.end() - 1, posix::StrDup(argument));
+  }
+
+  template <typename Str>
+  void AddArguments(const ::std::vector<Str>& arguments) {
+    for (typename ::std::vector<Str>::const_iterator i = arguments.begin();
+         i != arguments.end();
+         ++i) {
+      args_.insert(args_.end() - 1, posix::StrDup(i->c_str()));
+    }
+  }
+  char* const* Argv() {
+    return &args_[0];
+  }
+ private:
+  std::vector<char*> args_;
+};
+
+// A struct that encompasses the arguments to the child process of a
+// threadsafe-style death test process.
+struct ExecDeathTestArgs {
+  char* const* argv;  // Command-line arguments for the child's call to exec
+  int close_fd;       // File descriptor to close; the read end of a pipe
+};
+
+#if GTEST_OS_MAC
+inline char** GetEnviron() {
+  // When Google Test is built as a framework on MacOS X, the environ variable
+  // is unavailable. Apple's documentation (man environ) recommends using
+  // _NSGetEnviron() instead.
+  return *_NSGetEnviron();
+}
+#else
+// Some POSIX platforms expect you to declare environ. extern "C" makes
+// it reside in the global namespace.
+extern "C" char** environ;
+inline char** GetEnviron() { return environ; }
+#endif  // GTEST_OS_MAC
+
+// The main function for a threadsafe-style death test child process.
+// This function is called in a clone()-ed process and thus must avoid
+// any potentially unsafe operations like malloc or libc functions.
+static int ExecDeathTestChildMain(void* child_arg) {
+  ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg);
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd));
+
+  // We need to execute the test program in the same environment where
+  // it was originally invoked.  Therefore we change to the original
+  // working directory first.
+  const char* const original_dir =
+      UnitTest::GetInstance()->original_working_dir();
+  // We can safely call chdir() as it's a direct system call.
+  if (chdir(original_dir) != 0) {
+    DeathTestAbort(String::Format("chdir(\"%s\") failed: %s",
+                                  original_dir,
+                                  GetLastErrnoDescription().c_str()));
+    return EXIT_FAILURE;
+  }
+
+  // We can safely call execve() as it's a direct system call.  We
+  // cannot use execvp() as it's a libc function and thus potentially
+  // unsafe.  Since execve() doesn't search the PATH, the user must
+  // invoke the test program via a valid path that contains at least
+  // one path separator.
+  execve(args->argv[0], args->argv, GetEnviron());
+  DeathTestAbort(String::Format("execve(%s, ...) in %s failed: %s",
+                                args->argv[0],
+                                original_dir,
+                                GetLastErrnoDescription().c_str()));
+  return EXIT_FAILURE;
+}
+
+// Two utility routines that together determine the direction the stack
+// grows.
+// This could be accomplished more elegantly by a single recursive
+// function, but we want to guard against the unlikely possibility of
+// a smart compiler optimizing the recursion away.
+bool StackLowerThanAddress(const void* ptr) {
+  int dummy;
+  return &dummy < ptr;
+}
+
+bool StackGrowsDown() {
+  int dummy;
+  return StackLowerThanAddress(&dummy);
+}
+
+// A threadsafe implementation of fork(2) for threadsafe-style death tests
+// that uses clone(2).  It dies with an error message if anything goes
+// wrong.
+static pid_t ExecDeathTestFork(char* const* argv, int close_fd) {
+  ExecDeathTestArgs args = { argv, close_fd };
+  pid_t child_pid = -1;
+
+#if GTEST_HAS_CLONE
+  const bool use_fork = GTEST_FLAG(death_test_use_fork);
+
+  if (!use_fork) {
+    static const bool stack_grows_down = StackGrowsDown();
+    const size_t stack_size = getpagesize();
+    // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead.
+    void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE,
+                             MAP_ANON | MAP_PRIVATE, -1, 0);
+    GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED);
+    void* const stack_top =
+        static_cast<char*>(stack) + (stack_grows_down ? stack_size : 0);
+
+    child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args);
+
+    GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1);
+  }
+#else
+  const bool use_fork = true;
+#endif  // GTEST_HAS_CLONE
+
+  if (use_fork && (child_pid = fork()) == 0) {
+      ExecDeathTestChildMain(&args);
+      _exit(0);
+  }
+
+  GTEST_DEATH_TEST_CHECK_(child_pid != -1);
+  return child_pid;
+}
+
+// The AssumeRole process for a fork-and-exec death test.  It re-executes the
+// main program from the beginning, setting the --gtest_filter
+// and --gtest_internal_run_death_test flags to cause only the current
+// death test to be re-run.
+DeathTest::TestRole ExecDeathTest::AssumeRole() {
+  const UnitTestImpl* const impl = GetUnitTestImpl();
+  const InternalRunDeathTestFlag* const flag =
+      impl->internal_run_death_test_flag();
+  const TestInfo* const info = impl->current_test_info();
+  const int death_test_index = info->result()->death_test_count();
+
+  if (flag != NULL) {
+    set_write_fd(flag->write_fd());
+    return EXECUTE_TEST;
+  }
+
+  int pipe_fd[2];
+  GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1);
+  // Clear the close-on-exec flag on the write end of the pipe, lest
+  // it be closed when the child process does an exec:
+  GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1);
+
+  const String filter_flag =
+      String::Format("--%s%s=%s.%s",
+                     GTEST_FLAG_PREFIX_, kFilterFlag,
+                     info->test_case_name(), info->name());
+  const String internal_flag =
+      String::Format("--%s%s=%s|%d|%d|%d",
+                     GTEST_FLAG_PREFIX_, kInternalRunDeathTestFlag,
+                     file_, line_, death_test_index, pipe_fd[1]);
+  Arguments args;
+  args.AddArguments(GetArgvs());
+  args.AddArgument(filter_flag.c_str());
+  args.AddArgument(internal_flag.c_str());
+
+  DeathTest::set_last_death_test_message("");
+
+  CaptureStderr();
+  // See the comment in NoExecDeathTest::AssumeRole for why the next line
+  // is necessary.
+  FlushInfoLog();
+
+  const pid_t child_pid = ExecDeathTestFork(args.Argv(), pipe_fd[0]);
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
+  set_child_pid(child_pid);
+  set_read_fd(pipe_fd[0]);
+  set_spawned(true);
+  return OVERSEE_TEST;
+}
+
+#endif  // !GTEST_OS_WINDOWS
+
+// Creates a concrete DeathTest-derived class that depends on the
+// --gtest_death_test_style flag, and sets the pointer pointed to
+// by the "test" argument to its address.  If the test should be
+// skipped, sets that pointer to NULL.  Returns true, unless the
+// flag is set to an invalid value.
+bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
+                                     const char* file, int line,
+                                     DeathTest** test) {
+  UnitTestImpl* const impl = GetUnitTestImpl();
+  const InternalRunDeathTestFlag* const flag =
+      impl->internal_run_death_test_flag();
+  const int death_test_index = impl->current_test_info()
+      ->increment_death_test_count();
+
+  if (flag != NULL) {
+    if (death_test_index > flag->index()) {
+      DeathTest::set_last_death_test_message(String::Format(
+          "Death test count (%d) somehow exceeded expected maximum (%d)",
+          death_test_index, flag->index()));
+      return false;
+    }
+
+    if (!(flag->file() == file && flag->line() == line &&
+          flag->index() == death_test_index)) {
+      *test = NULL;
+      return true;
+    }
+  }
+
+#if GTEST_OS_WINDOWS
+  if (GTEST_FLAG(death_test_style) == "threadsafe" ||
+      GTEST_FLAG(death_test_style) == "fast") {
+    *test = new WindowsDeathTest(statement, regex, file, line);
+  }
+#else
+  if (GTEST_FLAG(death_test_style) == "threadsafe") {
+    *test = new ExecDeathTest(statement, regex, file, line);
+  } else if (GTEST_FLAG(death_test_style) == "fast") {
+    *test = new NoExecDeathTest(statement, regex);
+  }
+#endif  // GTEST_OS_WINDOWS
+  else {  // NOLINT - this is more readable than unbalanced brackets inside #if.
+    DeathTest::set_last_death_test_message(String::Format(
+        "Unknown death test style \"%s\" encountered",
+        GTEST_FLAG(death_test_style).c_str()));
+    return false;
+  }
+
+  return true;
+}
+
+// Splits a given string on a given delimiter, populating a given
+// vector with the fields.  GTEST_HAS_DEATH_TEST implies that we have
+// ::std::string, so we can use it here.
+static void SplitString(const ::std::string& str, char delimiter,
+                        ::std::vector< ::std::string>* dest) {
+  ::std::vector< ::std::string> parsed;
+  ::std::string::size_type pos = 0;
+  while (::testing::internal::AlwaysTrue()) {
+    const ::std::string::size_type colon = str.find(delimiter, pos);
+    if (colon == ::std::string::npos) {
+      parsed.push_back(str.substr(pos));
+      break;
+    } else {
+      parsed.push_back(str.substr(pos, colon - pos));
+      pos = colon + 1;
+    }
+  }
+  dest->swap(parsed);
+}
+
+#if GTEST_OS_WINDOWS
+// Recreates the pipe and event handles from the provided parameters,
+// signals the event, and returns a file descriptor wrapped around the pipe
+// handle. This function is called in the child process only.
+int GetStatusFileDescriptor(unsigned int parent_process_id,
+                            size_t write_handle_as_size_t,
+                            size_t event_handle_as_size_t) {
+  AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE,
+                                                   FALSE,  // Non-inheritable.
+                                                   parent_process_id));
+  if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) {
+    DeathTestAbort(String::Format("Unable to open parent process %u",
+                                  parent_process_id));
+  }
+
+  // TODO(vladl@google.com): Replace the following check with a
+  // compile-time assertion when available.
+  GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t));
+
+  const HANDLE write_handle =
+      reinterpret_cast<HANDLE>(write_handle_as_size_t);
+  HANDLE dup_write_handle;
+
+  // The newly initialized handle is accessible only in in the parent
+  // process. To obtain one accessible within the child, we need to use
+  // DuplicateHandle.
+  if (!::DuplicateHandle(parent_process_handle.Get(), write_handle,
+                         ::GetCurrentProcess(), &dup_write_handle,
+                         0x0,    // Requested privileges ignored since
+                                 // DUPLICATE_SAME_ACCESS is used.
+                         FALSE,  // Request non-inheritable handler.
+                         DUPLICATE_SAME_ACCESS)) {
+    DeathTestAbort(String::Format(
+        "Unable to duplicate the pipe handle %Iu from the parent process %u",
+        write_handle_as_size_t, parent_process_id));
+  }
+
+  const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t);
+  HANDLE dup_event_handle;
+
+  if (!::DuplicateHandle(parent_process_handle.Get(), event_handle,
+                         ::GetCurrentProcess(), &dup_event_handle,
+                         0x0,
+                         FALSE,
+                         DUPLICATE_SAME_ACCESS)) {
+    DeathTestAbort(String::Format(
+        "Unable to duplicate the event handle %Iu from the parent process %u",
+        event_handle_as_size_t, parent_process_id));
+  }
+
+  const int write_fd =
+      ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND);
+  if (write_fd == -1) {
+    DeathTestAbort(String::Format(
+        "Unable to convert pipe handle %Iu to a file descriptor",
+        write_handle_as_size_t));
+  }
+
+  // Signals the parent that the write end of the pipe has been acquired
+  // so the parent can release its own write end.
+  ::SetEvent(dup_event_handle);
+
+  return write_fd;
+}
+#endif  // GTEST_OS_WINDOWS
+
+// Returns a newly created InternalRunDeathTestFlag object with fields
+// initialized from the GTEST_FLAG(internal_run_death_test) flag if
+// the flag is specified; otherwise returns NULL.
+InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
+  if (GTEST_FLAG(internal_run_death_test) == "") return NULL;
+
+  // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we
+  // can use it here.
+  int line = -1;
+  int index = -1;
+  ::std::vector< ::std::string> fields;
+  SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields);
+  int write_fd = -1;
+
+#if GTEST_OS_WINDOWS
+  unsigned int parent_process_id = 0;
+  size_t write_handle_as_size_t = 0;
+  size_t event_handle_as_size_t = 0;
+
+  if (fields.size() != 6
+      || !ParseNaturalNumber(fields[1], &line)
+      || !ParseNaturalNumber(fields[2], &index)
+      || !ParseNaturalNumber(fields[3], &parent_process_id)
+      || !ParseNaturalNumber(fields[4], &write_handle_as_size_t)
+      || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) {
+    DeathTestAbort(String::Format(
+        "Bad --gtest_internal_run_death_test flag: %s",
+        GTEST_FLAG(internal_run_death_test).c_str()));
+  }
+  write_fd = GetStatusFileDescriptor(parent_process_id,
+                                     write_handle_as_size_t,
+                                     event_handle_as_size_t);
+#else
+  if (fields.size() != 4
+      || !ParseNaturalNumber(fields[1], &line)
+      || !ParseNaturalNumber(fields[2], &index)
+      || !ParseNaturalNumber(fields[3], &write_fd)) {
+    DeathTestAbort(String::Format(
+        "Bad --gtest_internal_run_death_test flag: %s",
+        GTEST_FLAG(internal_run_death_test).c_str()));
+  }
+#endif  // GTEST_OS_WINDOWS
+  return new InternalRunDeathTestFlag(fields[0], line, index, write_fd);
+}
+
+}  // namespace internal
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+}  // namespace testing
diff --git a/src/LLVM/utils/unittest/googletest/gtest-filepath.cc b/src/LLVM/utils/unittest/googletest/gtest-filepath.cc
new file mode 100644
index 0000000..c1ef918
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/gtest-filepath.cc
@@ -0,0 +1,380 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: keith.ray@gmail.com (Keith Ray)
+
+#include <gtest/internal/gtest-filepath.h>
+#include <gtest/internal/gtest-port.h>
+
+#include <stdlib.h>
+
+#if GTEST_OS_WINDOWS_MOBILE
+#include <windows.h>
+#elif GTEST_OS_WINDOWS
+#include <direct.h>
+#include <io.h>
+#elif GTEST_OS_SYMBIAN
+// Symbian OpenC has PATH_MAX in sys/syslimits.h
+#include <sys/syslimits.h>
+#else
+#include <limits.h>
+#include <climits>  // Some Linux distributions define PATH_MAX here.
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+#if GTEST_OS_WINDOWS
+#define GTEST_PATH_MAX_ _MAX_PATH
+#elif defined(PATH_MAX)
+#define GTEST_PATH_MAX_ PATH_MAX
+#elif defined(_XOPEN_PATH_MAX)
+#define GTEST_PATH_MAX_ _XOPEN_PATH_MAX
+#else
+#define GTEST_PATH_MAX_ _POSIX_PATH_MAX
+#endif  // GTEST_OS_WINDOWS
+
+#include <gtest/internal/gtest-string.h>
+
+namespace testing {
+namespace internal {
+
+#if GTEST_OS_WINDOWS
+// On Windows, '\\' is the standard path separator, but many tools and the
+// Windows API also accept '/' as an alternate path separator. Unless otherwise
+// noted, a file path can contain either kind of path separators, or a mixture
+// of them.
+const char kPathSeparator = '\\';
+const char kAlternatePathSeparator = '/';
+const char kPathSeparatorString[] = "\\";
+const char kAlternatePathSeparatorString[] = "/";
+#if GTEST_OS_WINDOWS_MOBILE
+// Windows CE doesn't have a current directory. You should not use
+// the current directory in tests on Windows CE, but this at least
+// provides a reasonable fallback.
+const char kCurrentDirectoryString[] = "\\";
+// Windows CE doesn't define INVALID_FILE_ATTRIBUTES
+const DWORD kInvalidFileAttributes = 0xffffffff;
+#else
+const char kCurrentDirectoryString[] = ".\\";
+#endif  // GTEST_OS_WINDOWS_MOBILE
+#else
+const char kPathSeparator = '/';
+const char kPathSeparatorString[] = "/";
+const char kCurrentDirectoryString[] = "./";
+#endif  // GTEST_OS_WINDOWS
+
+// Returns whether the given character is a valid path separator.
+static bool IsPathSeparator(char c) {
+#if GTEST_HAS_ALT_PATH_SEP_
+  return (c == kPathSeparator) || (c == kAlternatePathSeparator);
+#else
+  return c == kPathSeparator;
+#endif
+}
+
+// Returns the current working directory, or "" if unsuccessful.
+FilePath FilePath::GetCurrentDir() {
+#if GTEST_OS_WINDOWS_MOBILE
+  // Windows CE doesn't have a current directory, so we just return
+  // something reasonable.
+  return FilePath(kCurrentDirectoryString);
+#elif GTEST_OS_WINDOWS
+  char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
+  return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
+#else
+  char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
+  return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
+#endif  // GTEST_OS_WINDOWS_MOBILE
+}
+
+// Returns a copy of the FilePath with the case-insensitive extension removed.
+// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
+// FilePath("dir/file"). If a case-insensitive extension is not
+// found, returns a copy of the original FilePath.
+FilePath FilePath::RemoveExtension(const char* extension) const {
+  String dot_extension(String::Format(".%s", extension));
+  if (pathname_.EndsWithCaseInsensitive(dot_extension.c_str())) {
+    return FilePath(String(pathname_.c_str(), pathname_.length() - 4));
+  }
+  return *this;
+}
+
+// Returns a pointer to the last occurence of a valid path separator in
+// the FilePath. On Windows, for example, both '/' and '\' are valid path
+// separators. Returns NULL if no path separator was found.
+const char* FilePath::FindLastPathSeparator() const {
+  const char* const last_sep = strrchr(c_str(), kPathSeparator);
+#if GTEST_HAS_ALT_PATH_SEP_
+  const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);
+  // Comparing two pointers of which only one is NULL is undefined.
+  if (last_alt_sep != NULL &&
+      (last_sep == NULL || last_alt_sep > last_sep)) {
+    return last_alt_sep;
+  }
+#endif
+  return last_sep;
+}
+
+// Returns a copy of the FilePath with the directory part removed.
+// Example: FilePath("path/to/file").RemoveDirectoryName() returns
+// FilePath("file"). If there is no directory part ("just_a_file"), it returns
+// the FilePath unmodified. If there is no file part ("just_a_dir/") it
+// returns an empty FilePath ("").
+// On Windows platform, '\' is the path separator, otherwise it is '/'.
+FilePath FilePath::RemoveDirectoryName() const {
+  const char* const last_sep = FindLastPathSeparator();
+  return last_sep ? FilePath(String(last_sep + 1)) : *this;
+}
+
+// RemoveFileName returns the directory path with the filename removed.
+// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
+// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
+// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
+// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
+// On Windows platform, '\' is the path separator, otherwise it is '/'.
+FilePath FilePath::RemoveFileName() const {
+  const char* const last_sep = FindLastPathSeparator();
+  String dir;
+  if (last_sep) {
+    dir = String(c_str(), last_sep + 1 - c_str());
+  } else {
+    dir = kCurrentDirectoryString;
+  }
+  return FilePath(dir);
+}
+
+// Helper functions for naming files in a directory for xml output.
+
+// Given directory = "dir", base_name = "test", number = 0,
+// extension = "xml", returns "dir/test.xml". If number is greater
+// than zero (e.g., 12), returns "dir/test_12.xml".
+// On Windows platform, uses \ as the separator rather than /.
+FilePath FilePath::MakeFileName(const FilePath& directory,
+                                const FilePath& base_name,
+                                int number,
+                                const char* extension) {
+  String file;
+  if (number == 0) {
+    file = String::Format("%s.%s", base_name.c_str(), extension);
+  } else {
+    file = String::Format("%s_%d.%s", base_name.c_str(), number, extension);
+  }
+  return ConcatPaths(directory, FilePath(file));
+}
+
+// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml".
+// On Windows, uses \ as the separator rather than /.
+FilePath FilePath::ConcatPaths(const FilePath& directory,
+                               const FilePath& relative_path) {
+  if (directory.IsEmpty())
+    return relative_path;
+  const FilePath dir(directory.RemoveTrailingPathSeparator());
+  return FilePath(String::Format("%s%c%s", dir.c_str(), kPathSeparator,
+                                 relative_path.c_str()));
+}
+
+// Returns true if pathname describes something findable in the file-system,
+// either a file, directory, or whatever.
+bool FilePath::FileOrDirectoryExists() const {
+#if GTEST_OS_WINDOWS_MOBILE
+  LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());
+  const DWORD attributes = GetFileAttributes(unicode);
+  delete [] unicode;
+  return attributes != kInvalidFileAttributes;
+#else
+  posix::StatStruct file_stat;
+  return posix::Stat(pathname_.c_str(), &file_stat) == 0;
+#endif  // GTEST_OS_WINDOWS_MOBILE
+}
+
+// Returns true if pathname describes a directory in the file-system
+// that exists.
+bool FilePath::DirectoryExists() const {
+  bool result = false;
+#if GTEST_OS_WINDOWS
+  // Don't strip off trailing separator if path is a root directory on
+  // Windows (like "C:\\").
+  const FilePath& path(IsRootDirectory() ? *this :
+                                           RemoveTrailingPathSeparator());
+#else
+  const FilePath& path(*this);
+#endif
+
+#if GTEST_OS_WINDOWS_MOBILE
+  LPCWSTR unicode = String::AnsiToUtf16(path.c_str());
+  const DWORD attributes = GetFileAttributes(unicode);
+  delete [] unicode;
+  if ((attributes != kInvalidFileAttributes) &&
+      (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
+    result = true;
+  }
+#else
+  posix::StatStruct file_stat;
+  result = posix::Stat(path.c_str(), &file_stat) == 0 &&
+      posix::IsDir(file_stat);
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+  return result;
+}
+
+// Returns true if pathname describes a root directory. (Windows has one
+// root directory per disk drive.)
+bool FilePath::IsRootDirectory() const {
+#if GTEST_OS_WINDOWS
+  // TODO(wan@google.com): on Windows a network share like
+  // \\server\share can be a root directory, although it cannot be the
+  // current directory.  Handle this properly.
+  return pathname_.length() == 3 && IsAbsolutePath();
+#else
+  return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
+#endif
+}
+
+// Returns true if pathname describes an absolute path.
+bool FilePath::IsAbsolutePath() const {
+  const char* const name = pathname_.c_str();
+#if GTEST_OS_WINDOWS
+  return pathname_.length() >= 3 &&
+     ((name[0] >= 'a' && name[0] <= 'z') ||
+      (name[0] >= 'A' && name[0] <= 'Z')) &&
+     name[1] == ':' &&
+     IsPathSeparator(name[2]);
+#else
+  return IsPathSeparator(name[0]);
+#endif
+}
+
+// Returns a pathname for a file that does not currently exist. The pathname
+// will be directory/base_name.extension or
+// directory/base_name_<number>.extension if directory/base_name.extension
+// already exists. The number will be incremented until a pathname is found
+// that does not already exist.
+// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
+// There could be a race condition if two or more processes are calling this
+// function at the same time -- they could both pick the same filename.
+FilePath FilePath::GenerateUniqueFileName(const FilePath& directory,
+                                          const FilePath& base_name,
+                                          const char* extension) {
+  FilePath full_pathname;
+  int number = 0;
+  do {
+    full_pathname.Set(MakeFileName(directory, base_name, number++, extension));
+  } while (full_pathname.FileOrDirectoryExists());
+  return full_pathname;
+}
+
+// Returns true if FilePath ends with a path separator, which indicates that
+// it is intended to represent a directory. Returns false otherwise.
+// This does NOT check that a directory (or file) actually exists.
+bool FilePath::IsDirectory() const {
+  return !pathname_.empty() &&
+         IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);
+}
+
+// Create directories so that path exists. Returns true if successful or if
+// the directories already exist; returns false if unable to create directories
+// for any reason.
+bool FilePath::CreateDirectoriesRecursively() const {
+  if (!this->IsDirectory()) {
+    return false;
+  }
+
+  if (pathname_.length() == 0 || this->DirectoryExists()) {
+    return true;
+  }
+
+  const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName());
+  return parent.CreateDirectoriesRecursively() && this->CreateFolder();
+}
+
+// Create the directory so that path exists. Returns true if successful or
+// if the directory already exists; returns false if unable to create the
+// directory for any reason, including if the parent directory does not
+// exist. Not named "CreateDirectory" because that's a macro on Windows.
+bool FilePath::CreateFolder() const {
+#if GTEST_OS_WINDOWS_MOBILE
+  FilePath removed_sep(this->RemoveTrailingPathSeparator());
+  LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
+  int result = CreateDirectory(unicode, NULL) ? 0 : -1;
+  delete [] unicode;
+#elif GTEST_OS_WINDOWS
+  int result = _mkdir(pathname_.c_str());
+#else
+  int result = mkdir(pathname_.c_str(), 0777);
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+  if (result == -1) {
+    return this->DirectoryExists();  // An error is OK if the directory exists.
+  }
+  return true;  // No error.
+}
+
+// If input name has a trailing separator character, remove it and return the
+// name, otherwise return the name string unmodified.
+// On Windows platform, uses \ as the separator, other platforms use /.
+FilePath FilePath::RemoveTrailingPathSeparator() const {
+  return IsDirectory()
+      ? FilePath(String(pathname_.c_str(), pathname_.length() - 1))
+      : *this;
+}
+
+// Removes any redundant separators that might be in the pathname.
+// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
+// redundancies that might be in a pathname involving "." or "..".
+// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share).
+void FilePath::Normalize() {
+  if (pathname_.c_str() == NULL) {
+    pathname_ = "";
+    return;
+  }
+  const char* src = pathname_.c_str();
+  char* const dest = new char[pathname_.length() + 1];
+  char* dest_ptr = dest;
+  memset(dest_ptr, 0, pathname_.length() + 1);
+
+  while (*src != '\0') {
+    *dest_ptr = *src;
+    if (!IsPathSeparator(*src)) {
+      src++;
+    } else {
+#if GTEST_HAS_ALT_PATH_SEP_
+      if (*dest_ptr == kAlternatePathSeparator) {
+        *dest_ptr = kPathSeparator;
+      }
+#endif
+      while (IsPathSeparator(*src))
+        src++;
+    }
+    dest_ptr++;
+  }
+  *dest_ptr = '\0';
+  pathname_ = dest;
+  delete[] dest;
+}
+
+}  // namespace internal
+}  // namespace testing
diff --git a/src/LLVM/utils/unittest/googletest/gtest-port.cc b/src/LLVM/utils/unittest/googletest/gtest-port.cc
new file mode 100644
index 0000000..5609599
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/gtest-port.cc
@@ -0,0 +1,711 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+#include <gtest/internal/gtest-port.h>
+
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#if GTEST_OS_WINDOWS_MOBILE
+#include <windows.h>  // For TerminateProcess()
+#elif GTEST_OS_WINDOWS
+#include <io.h>
+#include <sys/stat.h>
+#else
+#include <unistd.h>
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+#if GTEST_OS_MAC
+#include <mach/mach_init.h>
+#include <mach/task.h>
+#include <mach/vm_map.h>
+#endif  // GTEST_OS_MAC
+
+#include <gtest/gtest-spi.h>
+#include <gtest/gtest-message.h>
+#include <gtest/internal/gtest-string.h>
+
+// Indicates that this translation unit is part of Google Test's
+// implementation.  It must come before gtest-internal-inl.h is
+// included, or there will be a compiler error.  This trick is to
+// prevent a user from accidentally including gtest-internal-inl.h in
+// his code.
+#define GTEST_IMPLEMENTATION_ 1
+#include "gtest/internal/gtest-internal-inl.h"
+#undef GTEST_IMPLEMENTATION_
+
+namespace testing {
+namespace internal {
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+// MSVC and C++Builder do not provide a definition of STDERR_FILENO.
+const int kStdOutFileno = 1;
+const int kStdErrFileno = 2;
+#else
+const int kStdOutFileno = STDOUT_FILENO;
+const int kStdErrFileno = STDERR_FILENO;
+#endif  // _MSC_VER
+
+#if GTEST_OS_MAC
+
+// Returns the number of threads running in the process, or 0 to indicate that
+// we cannot detect it.
+size_t GetThreadCount() {
+  const task_t task = mach_task_self();
+  mach_msg_type_number_t thread_count;
+  thread_act_array_t thread_list;
+  const kern_return_t status = task_threads(task, &thread_list, &thread_count);
+  if (status == KERN_SUCCESS) {
+    // task_threads allocates resources in thread_list and we need to free them
+    // to avoid leaks.
+    vm_deallocate(task,
+                  reinterpret_cast<vm_address_t>(thread_list),
+                  sizeof(thread_t) * thread_count);
+    return static_cast<size_t>(thread_count);
+  } else {
+    return 0;
+  }
+}
+
+#else
+
+size_t GetThreadCount() {
+  // There's no portable way to detect the number of threads, so we just
+  // return 0 to indicate that we cannot detect it.
+  return 0;
+}
+
+#endif  // GTEST_OS_MAC
+
+#if GTEST_USES_POSIX_RE
+
+// Implements RE.  Currently only needed for death tests.
+
+RE::~RE() {
+  if (is_valid_) {
+    // regfree'ing an invalid regex might crash because the content
+    // of the regex is undefined. Since the regex's are essentially
+    // the same, one cannot be valid (or invalid) without the other
+    // being so too.
+    regfree(&partial_regex_);
+    regfree(&full_regex_);
+  }
+  free(const_cast<char*>(pattern_));
+}
+
+// Returns true iff regular expression re matches the entire str.
+bool RE::FullMatch(const char* str, const RE& re) {
+  if (!re.is_valid_) return false;
+
+  regmatch_t match;
+  return regexec(&re.full_regex_, str, 1, &match, 0) == 0;
+}
+
+// Returns true iff regular expression re matches a substring of str
+// (including str itself).
+bool RE::PartialMatch(const char* str, const RE& re) {
+  if (!re.is_valid_) return false;
+
+  regmatch_t match;
+  return regexec(&re.partial_regex_, str, 1, &match, 0) == 0;
+}
+
+// Initializes an RE from its string representation.
+void RE::Init(const char* regex) {
+  pattern_ = posix::StrDup(regex);
+
+  // Reserves enough bytes to hold the regular expression used for a
+  // full match.
+  const size_t full_regex_len = strlen(regex) + 10;
+  char* const full_pattern = new char[full_regex_len];
+
+  snprintf(full_pattern, full_regex_len, "^(%s)$", regex);
+  is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;
+  // We want to call regcomp(&partial_regex_, ...) even if the
+  // previous expression returns false.  Otherwise partial_regex_ may
+  // not be properly initialized can may cause trouble when it's
+  // freed.
+  //
+  // Some implementation of POSIX regex (e.g. on at least some
+  // versions of Cygwin) doesn't accept the empty string as a valid
+  // regex.  We change it to an equivalent form "()" to be safe.
+  if (is_valid_) {
+    const char* const partial_regex = (*regex == '\0') ? "()" : regex;
+    is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
+  }
+  EXPECT_TRUE(is_valid_)
+      << "Regular expression \"" << regex
+      << "\" is not a valid POSIX Extended regular expression.";
+
+  delete[] full_pattern;
+}
+
+#elif GTEST_USES_SIMPLE_RE
+
+// Returns true iff ch appears anywhere in str (excluding the
+// terminating '\0' character).
+bool IsInSet(char ch, const char* str) {
+  return ch != '\0' && strchr(str, ch) != NULL;
+}
+
+// Returns true iff ch belongs to the given classification.  Unlike
+// similar functions in <ctype.h>, these aren't affected by the
+// current locale.
+bool IsDigit(char ch) { return '0' <= ch && ch <= '9'; }
+bool IsPunct(char ch) {
+  return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~");
+}
+bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); }
+bool IsWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); }
+bool IsWordChar(char ch) {
+  return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ||
+      ('0' <= ch && ch <= '9') || ch == '_';
+}
+
+// Returns true iff "\\c" is a supported escape sequence.
+bool IsValidEscape(char c) {
+  return (IsPunct(c) || IsInSet(c, "dDfnrsStvwW"));
+}
+
+// Returns true iff the given atom (specified by escaped and pattern)
+// matches ch.  The result is undefined if the atom is invalid.
+bool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
+  if (escaped) {  // "\\p" where p is pattern_char.
+    switch (pattern_char) {
+      case 'd': return IsDigit(ch);
+      case 'D': return !IsDigit(ch);
+      case 'f': return ch == '\f';
+      case 'n': return ch == '\n';
+      case 'r': return ch == '\r';
+      case 's': return IsWhiteSpace(ch);
+      case 'S': return !IsWhiteSpace(ch);
+      case 't': return ch == '\t';
+      case 'v': return ch == '\v';
+      case 'w': return IsWordChar(ch);
+      case 'W': return !IsWordChar(ch);
+    }
+    return IsPunct(pattern_char) && pattern_char == ch;
+  }
+
+  return (pattern_char == '.' && ch != '\n') || pattern_char == ch;
+}
+
+// Helper function used by ValidateRegex() to format error messages.
+String FormatRegexSyntaxError(const char* regex, int index) {
+  return (Message() << "Syntax error at index " << index
+          << " in simple regular expression \"" << regex << "\": ").GetString();
+}
+
+// Generates non-fatal failures and returns false if regex is invalid;
+// otherwise returns true.
+bool ValidateRegex(const char* regex) {
+  if (regex == NULL) {
+    // TODO(wan@google.com): fix the source file location in the
+    // assertion failures to match where the regex is used in user
+    // code.
+    ADD_FAILURE() << "NULL is not a valid simple regular expression.";
+    return false;
+  }
+
+  bool is_valid = true;
+
+  // True iff ?, *, or + can follow the previous atom.
+  bool prev_repeatable = false;
+  for (int i = 0; regex[i]; i++) {
+    if (regex[i] == '\\') {  // An escape sequence
+      i++;
+      if (regex[i] == '\0') {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
+                      << "'\\' cannot appear at the end.";
+        return false;
+      }
+
+      if (!IsValidEscape(regex[i])) {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
+                      << "invalid escape sequence \"\\" << regex[i] << "\".";
+        is_valid = false;
+      }
+      prev_repeatable = true;
+    } else {  // Not an escape sequence.
+      const char ch = regex[i];
+
+      if (ch == '^' && i > 0) {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
+                      << "'^' can only appear at the beginning.";
+        is_valid = false;
+      } else if (ch == '$' && regex[i + 1] != '\0') {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
+                      << "'$' can only appear at the end.";
+        is_valid = false;
+      } else if (IsInSet(ch, "()[]{}|")) {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
+                      << "'" << ch << "' is unsupported.";
+        is_valid = false;
+      } else if (IsRepeat(ch) && !prev_repeatable) {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
+                      << "'" << ch << "' can only follow a repeatable token.";
+        is_valid = false;
+      }
+
+      prev_repeatable = !IsInSet(ch, "^$?*+");
+    }
+  }
+
+  return is_valid;
+}
+
+// Matches a repeated regex atom followed by a valid simple regular
+// expression.  The regex atom is defined as c if escaped is false,
+// or \c otherwise.  repeat is the repetition meta character (?, *,
+// or +).  The behavior is undefined if str contains too many
+// characters to be indexable by size_t, in which case the test will
+// probably time out anyway.  We are fine with this limitation as
+// std::string has it too.
+bool MatchRepetitionAndRegexAtHead(
+    bool escaped, char c, char repeat, const char* regex,
+    const char* str) {
+  const size_t min_count = (repeat == '+') ? 1 : 0;
+  const size_t max_count = (repeat == '?') ? 1 :
+      static_cast<size_t>(-1) - 1;
+  // We cannot call numeric_limits::max() as it conflicts with the
+  // max() macro on Windows.
+
+  for (size_t i = 0; i <= max_count; ++i) {
+    // We know that the atom matches each of the first i characters in str.
+    if (i >= min_count && MatchRegexAtHead(regex, str + i)) {
+      // We have enough matches at the head, and the tail matches too.
+      // Since we only care about *whether* the pattern matches str
+      // (as opposed to *how* it matches), there is no need to find a
+      // greedy match.
+      return true;
+    }
+    if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i]))
+      return false;
+  }
+  return false;
+}
+
+// Returns true iff regex matches a prefix of str.  regex must be a
+// valid simple regular expression and not start with "^", or the
+// result is undefined.
+bool MatchRegexAtHead(const char* regex, const char* str) {
+  if (*regex == '\0')  // An empty regex matches a prefix of anything.
+    return true;
+
+  // "$" only matches the end of a string.  Note that regex being
+  // valid guarantees that there's nothing after "$" in it.
+  if (*regex == '$')
+    return *str == '\0';
+
+  // Is the first thing in regex an escape sequence?
+  const bool escaped = *regex == '\\';
+  if (escaped)
+    ++regex;
+  if (IsRepeat(regex[1])) {
+    // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so
+    // here's an indirect recursion.  It terminates as the regex gets
+    // shorter in each recursion.
+    return MatchRepetitionAndRegexAtHead(
+        escaped, regex[0], regex[1], regex + 2, str);
+  } else {
+    // regex isn't empty, isn't "$", and doesn't start with a
+    // repetition.  We match the first atom of regex with the first
+    // character of str and recurse.
+    return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) &&
+        MatchRegexAtHead(regex + 1, str + 1);
+  }
+}
+
+// Returns true iff regex matches any substring of str.  regex must be
+// a valid simple regular expression, or the result is undefined.
+//
+// The algorithm is recursive, but the recursion depth doesn't exceed
+// the regex length, so we won't need to worry about running out of
+// stack space normally.  In rare cases the time complexity can be
+// exponential with respect to the regex length + the string length,
+// but usually it's must faster (often close to linear).
+bool MatchRegexAnywhere(const char* regex, const char* str) {
+  if (regex == NULL || str == NULL)
+    return false;
+
+  if (*regex == '^')
+    return MatchRegexAtHead(regex + 1, str);
+
+  // A successful match can be anywhere in str.
+  do {
+    if (MatchRegexAtHead(regex, str))
+      return true;
+  } while (*str++ != '\0');
+  return false;
+}
+
+// Implements the RE class.
+
+RE::~RE() {
+  free(const_cast<char*>(pattern_));
+  free(const_cast<char*>(full_pattern_));
+}
+
+// Returns true iff regular expression re matches the entire str.
+bool RE::FullMatch(const char* str, const RE& re) {
+  return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str);
+}
+
+// Returns true iff regular expression re matches a substring of str
+// (including str itself).
+bool RE::PartialMatch(const char* str, const RE& re) {
+  return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str);
+}
+
+// Initializes an RE from its string representation.
+void RE::Init(const char* regex) {
+  pattern_ = full_pattern_ = NULL;
+  if (regex != NULL) {
+    pattern_ = posix::StrDup(regex);
+  }
+
+  is_valid_ = ValidateRegex(regex);
+  if (!is_valid_) {
+    // No need to calculate the full pattern when the regex is invalid.
+    return;
+  }
+
+  const size_t len = strlen(regex);
+  // Reserves enough bytes to hold the regular expression used for a
+  // full match: we need space to prepend a '^', append a '$', and
+  // terminate the string with '\0'.
+  char* buffer = static_cast<char*>(malloc(len + 3));
+  full_pattern_ = buffer;
+
+  if (*regex != '^')
+    *buffer++ = '^';  // Makes sure full_pattern_ starts with '^'.
+
+  // We don't use snprintf or strncpy, as they trigger a warning when
+  // compiled with VC++ 8.0.
+  memcpy(buffer, regex, len);
+  buffer += len;
+
+  if (len == 0 || regex[len - 1] != '$')
+    *buffer++ = '$';  // Makes sure full_pattern_ ends with '$'.
+
+  *buffer = '\0';
+}
+
+#endif  // GTEST_USES_POSIX_RE
+
+
+GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line)
+    : severity_(severity) {
+  const char* const marker =
+      severity == GTEST_INFO ?    "[  INFO ]" :
+      severity == GTEST_WARNING ? "[WARNING]" :
+      severity == GTEST_ERROR ?   "[ ERROR ]" : "[ FATAL ]";
+  GetStream() << ::std::endl << marker << " "
+              << FormatFileLocation(file, line).c_str() << ": ";
+}
+
+// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
+GTestLog::~GTestLog() {
+  GetStream() << ::std::endl;
+  if (severity_ == GTEST_FATAL) {
+    fflush(stderr);
+    posix::Abort();
+  }
+}
+// Disable Microsoft deprecation warnings for POSIX functions called from
+// this class (creat, dup, dup2, and close)
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4996)
+#endif  // _MSC_VER
+
+#if GTEST_HAS_STREAM_REDIRECTION_
+
+// Object that captures an output stream (stdout/stderr).
+class CapturedStream {
+ public:
+  // The ctor redirects the stream to a temporary file.
+  CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
+#if GTEST_OS_WINDOWS
+    char temp_dir_path[MAX_PATH + 1] = { '\0' };  // NOLINT
+    char temp_file_path[MAX_PATH + 1] = { '\0' };  // NOLINT
+
+    ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);
+    const UINT success = ::GetTempFileNameA(temp_dir_path,
+                                            "gtest_redir",
+                                            0,  // Generate unique file name.
+                                            temp_file_path);
+    GTEST_CHECK_(success != 0)
+        << "Unable to create a temporary file in " << temp_dir_path;
+    const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
+    GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file "
+                                    << temp_file_path;
+    filename_ = temp_file_path;
+#else
+    // There's no guarantee that a test has write access to the
+    // current directory, so we create the temporary file in the /tmp
+    // directory instead.
+    char name_template[] = "/tmp/captured_stream.XXXXXX";
+    const int captured_fd = mkstemp(name_template);
+    filename_ = name_template;
+#endif  // GTEST_OS_WINDOWS
+    fflush(NULL);
+    dup2(captured_fd, fd_);
+    close(captured_fd);
+  }
+
+  ~CapturedStream() {
+    remove(filename_.c_str());
+  }
+
+  String GetCapturedString() {
+    if (uncaptured_fd_ != -1) {
+      // Restores the original stream.
+      fflush(NULL);
+      dup2(uncaptured_fd_, fd_);
+      close(uncaptured_fd_);
+      uncaptured_fd_ = -1;
+    }
+
+    FILE* const file = posix::FOpen(filename_.c_str(), "r");
+    const String content = ReadEntireFile(file);
+    posix::FClose(file);
+    return content;
+  }
+
+ private:
+  // Reads the entire content of a file as a String.
+  static String ReadEntireFile(FILE* file);
+
+  // Returns the size (in bytes) of a file.
+  static size_t GetFileSize(FILE* file);
+
+  const int fd_;  // A stream to capture.
+  int uncaptured_fd_;
+  // Name of the temporary file holding the stderr output.
+  ::std::string filename_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);
+};
+
+// Returns the size (in bytes) of a file.
+size_t CapturedStream::GetFileSize(FILE* file) {
+  fseek(file, 0, SEEK_END);
+  return static_cast<size_t>(ftell(file));
+}
+
+// Reads the entire content of a file as a string.
+String CapturedStream::ReadEntireFile(FILE* file) {
+  const size_t file_size = GetFileSize(file);
+  char* const buffer = new char[file_size];
+
+  size_t bytes_last_read = 0;  // # of bytes read in the last fread()
+  size_t bytes_read = 0;       // # of bytes read so far
+
+  fseek(file, 0, SEEK_SET);
+
+  // Keeps reading the file until we cannot read further or the
+  // pre-determined file size is reached.
+  do {
+    bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file);
+    bytes_read += bytes_last_read;
+  } while (bytes_last_read > 0 && bytes_read < file_size);
+
+  const String content(buffer, bytes_read);
+  delete[] buffer;
+
+  return content;
+}
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif  // _MSC_VER
+
+static CapturedStream* g_captured_stderr = NULL;
+static CapturedStream* g_captured_stdout = NULL;
+
+// Starts capturing an output stream (stdout/stderr).
+void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {
+  if (*stream != NULL) {
+    GTEST_LOG_(FATAL) << "Only one " << stream_name
+                      << " capturer can exist at a time.";
+  }
+  *stream = new CapturedStream(fd);
+}
+
+// Stops capturing the output stream and returns the captured string.
+String GetCapturedStream(CapturedStream** captured_stream) {
+  const String content = (*captured_stream)->GetCapturedString();
+
+  delete *captured_stream;
+  *captured_stream = NULL;
+
+  return content;
+}
+
+// Starts capturing stdout.
+void CaptureStdout() {
+  CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout);
+}
+
+// Starts capturing stderr.
+void CaptureStderr() {
+  CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr);
+}
+
+// Stops capturing stdout and returns the captured string.
+String GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); }
+
+// Stops capturing stderr and returns the captured string.
+String GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); }
+
+#endif  // GTEST_HAS_STREAM_REDIRECTION_
+
+#if GTEST_HAS_DEATH_TEST
+
+// A copy of all command line arguments.  Set by InitGoogleTest().
+::std::vector<String> g_argvs;
+
+// Returns the command line as a vector of strings.
+const ::std::vector<String>& GetArgvs() { return g_argvs; }
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+#if GTEST_OS_WINDOWS_MOBILE
+namespace posix {
+void Abort() {
+  DebugBreak();
+  TerminateProcess(GetCurrentProcess(), 1);
+}
+}  // namespace posix
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+// Returns the name of the environment variable corresponding to the
+// given flag.  For example, FlagToEnvVar("foo") will return
+// "GTEST_FOO" in the open-source version.
+static String FlagToEnvVar(const char* flag) {
+  const String full_flag =
+      (Message() << GTEST_FLAG_PREFIX_ << flag).GetString();
+
+  Message env_var;
+  for (size_t i = 0; i != full_flag.length(); i++) {
+    env_var << static_cast<char>(toupper(full_flag.c_str()[i]));
+  }
+
+  return env_var.GetString();
+}
+
+// Parses 'str' for a 32-bit signed integer.  If successful, writes
+// the result to *value and returns true; otherwise leaves *value
+// unchanged and returns false.
+bool ParseInt32(const Message& src_text, const char* str, Int32* value) {
+  // Parses the environment variable as a decimal integer.
+  char* end = NULL;
+  const long long_value = strtol(str, &end, 10);  // NOLINT
+
+  // Has strtol() consumed all characters in the string?
+  if (*end != '\0') {
+    // No - an invalid character was encountered.
+    Message msg;
+    msg << "WARNING: " << src_text
+        << " is expected to be a 32-bit integer, but actually"
+        << " has value \"" << str << "\".\n";
+    printf("%s", msg.GetString().c_str());
+    fflush(stdout);
+    return false;
+  }
+
+  // Is the parsed value in the range of an Int32?
+  const Int32 result = static_cast<Int32>(long_value);
+  if (long_value == LONG_MAX || long_value == LONG_MIN ||
+      // The parsed value overflows as a long.  (strtol() returns
+      // LONG_MAX or LONG_MIN when the input overflows.)
+      result != long_value
+      // The parsed value overflows as an Int32.
+      ) {
+    Message msg;
+    msg << "WARNING: " << src_text
+        << " is expected to be a 32-bit integer, but actually"
+        << " has value " << str << ", which overflows.\n";
+    printf("%s", msg.GetString().c_str());
+    fflush(stdout);
+    return false;
+  }
+
+  *value = result;
+  return true;
+}
+
+// Reads and returns the Boolean environment variable corresponding to
+// the given flag; if it's not set, returns default_value.
+//
+// The value is considered true iff it's not "0".
+bool BoolFromGTestEnv(const char* flag, bool default_value) {
+  const String env_var = FlagToEnvVar(flag);
+  const char* const string_value = posix::GetEnv(env_var.c_str());
+  return string_value == NULL ?
+      default_value : strcmp(string_value, "0") != 0;
+}
+
+// Reads and returns a 32-bit integer stored in the environment
+// variable corresponding to the given flag; if it isn't set or
+// doesn't represent a valid 32-bit integer, returns default_value.
+Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
+  const String env_var = FlagToEnvVar(flag);
+  const char* const string_value = posix::GetEnv(env_var.c_str());
+  if (string_value == NULL) {
+    // The environment variable is not set.
+    return default_value;
+  }
+
+  Int32 result = default_value;
+  if (!ParseInt32(Message() << "Environment variable " << env_var,
+                  string_value, &result)) {
+    printf("The default value %s is used.\n",
+           (Message() << default_value).GetString().c_str());
+    fflush(stdout);
+    return default_value;
+  }
+
+  return result;
+}
+
+// Reads and returns the string environment variable corresponding to
+// the given flag; if it's not set, returns default_value.
+const char* StringFromGTestEnv(const char* flag, const char* default_value) {
+  const String env_var = FlagToEnvVar(flag);
+  const char* const value = posix::GetEnv(env_var.c_str());
+  return value == NULL ? default_value : value;
+}
+
+}  // namespace internal
+}  // namespace testing
diff --git a/src/LLVM/utils/unittest/googletest/gtest-test-part.cc b/src/LLVM/utils/unittest/googletest/gtest-test-part.cc
new file mode 100644
index 0000000..8249afe
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/gtest-test-part.cc
@@ -0,0 +1,110 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: mheule@google.com (Markus Heule)
+//
+// The Google C++ Testing Framework (Google Test)
+
+#include <gtest/gtest-test-part.h>
+
+// Indicates that this translation unit is part of Google Test's
+// implementation.  It must come before gtest-internal-inl.h is
+// included, or there will be a compiler error.  This trick is to
+// prevent a user from accidentally including gtest-internal-inl.h in
+// his code.
+#define GTEST_IMPLEMENTATION_ 1
+#include "gtest/internal/gtest-internal-inl.h"
+#undef GTEST_IMPLEMENTATION_
+
+namespace testing {
+
+using internal::GetUnitTestImpl;
+
+// Gets the summary of the failure message by omitting the stack trace
+// in it.
+internal::String TestPartResult::ExtractSummary(const char* message) {
+  const char* const stack_trace = strstr(message, internal::kStackTraceMarker);
+  return stack_trace == NULL ? internal::String(message) :
+      internal::String(message, stack_trace - message);
+}
+
+// Prints a TestPartResult object.
+std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
+  return os
+      << result.file_name() << ":" << result.line_number() << ": "
+      << (result.type() == TestPartResult::kSuccess ? "Success" :
+          result.type() == TestPartResult::kFatalFailure ? "Fatal failure" :
+          "Non-fatal failure") << ":\n"
+      << result.message() << std::endl;
+}
+
+// Appends a TestPartResult to the array.
+void TestPartResultArray::Append(const TestPartResult& result) {
+  array_.push_back(result);
+}
+
+// Returns the TestPartResult at the given index (0-based).
+const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {
+  if (index < 0 || index >= size()) {
+    printf("\nInvalid index (%d) into TestPartResultArray.\n", index);
+    internal::posix::Abort();
+  }
+
+  return array_[index];
+}
+
+// Returns the number of TestPartResult objects in the array.
+int TestPartResultArray::size() const {
+  return static_cast<int>(array_.size());
+}
+
+namespace internal {
+
+HasNewFatalFailureHelper::HasNewFatalFailureHelper()
+    : has_new_fatal_failure_(false),
+      original_reporter_(GetUnitTestImpl()->
+                         GetTestPartResultReporterForCurrentThread()) {
+  GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this);
+}
+
+HasNewFatalFailureHelper::~HasNewFatalFailureHelper() {
+  GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(
+      original_reporter_);
+}
+
+void HasNewFatalFailureHelper::ReportTestPartResult(
+    const TestPartResult& result) {
+  if (result.fatally_failed())
+    has_new_fatal_failure_ = true;
+  original_reporter_->ReportTestPartResult(result);
+}
+
+}  // namespace internal
+
+}  // namespace testing
diff --git a/src/LLVM/utils/unittest/googletest/gtest-typed-test.cc b/src/LLVM/utils/unittest/googletest/gtest-typed-test.cc
new file mode 100644
index 0000000..3cc4b5d
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/gtest-typed-test.cc
@@ -0,0 +1,110 @@
+// Copyright 2008 Google Inc.
+// All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+#include <gtest/gtest-typed-test.h>
+#include <gtest/gtest.h>
+
+namespace testing {
+namespace internal {
+
+#if GTEST_HAS_TYPED_TEST_P
+
+// Skips to the first non-space char in str. Returns an empty string if str
+// contains only whitespace characters.
+static const char* SkipSpaces(const char* str) {
+  while (isspace(*str))
+    str++;
+  return str;
+}
+
+// Verifies that registered_tests match the test names in
+// defined_test_names_; returns registered_tests if successful, or
+// aborts the program otherwise.
+const char* TypedTestCasePState::VerifyRegisteredTestNames(
+    const char* file, int line, const char* registered_tests) {
+  typedef ::std::set<const char*>::const_iterator DefinedTestIter;
+  registered_ = true;
+
+  // Skip initial whitespace in registered_tests since some
+  // preprocessors prefix stringizied literals with whitespace.
+  registered_tests = SkipSpaces(registered_tests);
+
+  Message errors;
+  ::std::set<String> tests;
+  for (const char* names = registered_tests; names != NULL;
+       names = SkipComma(names)) {
+    const String name = GetPrefixUntilComma(names);
+    if (tests.count(name) != 0) {
+      errors << "Test " << name << " is listed more than once.\n";
+      continue;
+    }
+
+    bool found = false;
+    for (DefinedTestIter it = defined_test_names_.begin();
+         it != defined_test_names_.end();
+         ++it) {
+      if (name == *it) {
+        found = true;
+        break;
+      }
+    }
+
+    if (found) {
+      tests.insert(name);
+    } else {
+      errors << "No test named " << name
+             << " can be found in this test case.\n";
+    }
+  }
+
+  for (DefinedTestIter it = defined_test_names_.begin();
+       it != defined_test_names_.end();
+       ++it) {
+    if (tests.count(*it) == 0) {
+      errors << "You forgot to list test " << *it << ".\n";
+    }
+  }
+
+  const String& errors_str = errors.GetString();
+  if (errors_str != "") {
+    fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
+            errors_str.c_str());
+    fflush(stderr);
+    posix::Abort();
+  }
+
+  return registered_tests;
+}
+
+#endif  // GTEST_HAS_TYPED_TEST_P
+
+}  // namespace internal
+}  // namespace testing
diff --git a/src/LLVM/utils/unittest/googletest/gtest.cc b/src/LLVM/utils/unittest/googletest/gtest.cc
new file mode 100644
index 0000000..aa2d5bb
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/gtest.cc
@@ -0,0 +1,4704 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// The Google C++ Testing Framework (Google Test)
+
+#include <gtest/gtest.h>
+#include <gtest/gtest-spi.h>
+
+#include <ctype.h>
+#include <math.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#include <algorithm>
+#include <ostream>
+#include <sstream>
+#include <vector>
+
+#if GTEST_OS_LINUX
+
+// TODO(kenton@google.com): Use autoconf to detect availability of
+// gettimeofday().
+#define GTEST_HAS_GETTIMEOFDAY_ 1
+
+#include <fcntl.h>
+#include <limits.h>
+#include <sched.h>
+// Declares vsnprintf().  This header is not available on Windows.
+#include <strings.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <string>
+#include <vector>
+
+#elif GTEST_OS_SYMBIAN
+#define GTEST_HAS_GETTIMEOFDAY_ 1
+#include <sys/time.h>  // NOLINT
+
+#elif GTEST_OS_ZOS
+#define GTEST_HAS_GETTIMEOFDAY_ 1
+#include <sys/time.h>  // NOLINT
+
+// On z/OS we additionally need strings.h for strcasecmp.
+#include <strings.h>  // NOLINT
+
+#elif GTEST_OS_WINDOWS_MOBILE  // We are on Windows CE.
+
+#include <windows.h>  // NOLINT
+
+#elif GTEST_OS_WINDOWS  // We are on Windows proper.
+
+#include <io.h>  // NOLINT
+#include <sys/timeb.h>  // NOLINT
+#include <sys/types.h>  // NOLINT
+#include <sys/stat.h>  // NOLINT
+
+#if GTEST_OS_WINDOWS_MINGW
+// MinGW has gettimeofday() but not _ftime64().
+// TODO(kenton@google.com): Use autoconf to detect availability of
+//   gettimeofday().
+// TODO(kenton@google.com): There are other ways to get the time on
+//   Windows, like GetTickCount() or GetSystemTimeAsFileTime().  MinGW
+//   supports these.  consider using them instead.
+#define GTEST_HAS_GETTIMEOFDAY_ 1
+#include <sys/time.h>  // NOLINT
+#endif  // GTEST_OS_WINDOWS_MINGW
+
+// cpplint thinks that the header is already included, so we want to
+// silence it.
+#include <windows.h>  // NOLINT
+
+#else
+
+// Assume other platforms have gettimeofday().
+// TODO(kenton@google.com): Use autoconf to detect availability of
+//   gettimeofday().
+#define GTEST_HAS_GETTIMEOFDAY_ 1
+
+// cpplint thinks that the header is already included, so we want to
+// silence it.
+#include <sys/time.h>  // NOLINT
+#include <unistd.h>  // NOLINT
+
+#endif  // GTEST_OS_LINUX
+
+#if GTEST_HAS_EXCEPTIONS
+#include <stdexcept>
+#endif
+
+// Indicates that this translation unit is part of Google Test's
+// implementation.  It must come before gtest-internal-inl.h is
+// included, or there will be a compiler error.  This trick is to
+// prevent a user from accidentally including gtest-internal-inl.h in
+// his code.
+#define GTEST_IMPLEMENTATION_ 1
+#include "gtest/internal/gtest-internal-inl.h"
+#undef GTEST_IMPLEMENTATION_
+
+#if GTEST_OS_WINDOWS
+#define vsnprintf _vsnprintf
+#endif  // GTEST_OS_WINDOWS
+
+namespace testing {
+
+using internal::CountIf;
+using internal::ForEach;
+using internal::GetElementOr;
+using internal::Shuffle;
+
+// Constants.
+
+// A test whose test case name or test name matches this filter is
+// disabled and not run.
+static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*";
+
+// A test case whose name matches this filter is considered a death
+// test case and will be run before test cases whose name doesn't
+// match this filter.
+static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*";
+
+// A test filter that matches everything.
+static const char kUniversalFilter[] = "*";
+
+// The default output file for XML output.
+static const char kDefaultOutputFile[] = "test_detail.xml";
+
+// The environment variable name for the test shard index.
+static const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
+// The environment variable name for the total number of test shards.
+static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
+// The environment variable name for the test shard status file.
+static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE";
+
+namespace internal {
+
+// The text used in failure messages to indicate the start of the
+// stack trace.
+const char kStackTraceMarker[] = "\nStack trace:\n";
+
+// g_help_flag is true iff the --help flag or an equivalent form is
+// specified on the command line.
+bool g_help_flag = false;
+
+}  // namespace internal
+
+GTEST_DEFINE_bool_(
+    also_run_disabled_tests,
+    internal::BoolFromGTestEnv("also_run_disabled_tests", false),
+    "Run disabled tests too, in addition to the tests normally being run.");
+
+GTEST_DEFINE_bool_(
+    break_on_failure,
+    internal::BoolFromGTestEnv("break_on_failure", false),
+    "True iff a failed assertion should be a debugger break-point.");
+
+GTEST_DEFINE_bool_(
+    catch_exceptions,
+    internal::BoolFromGTestEnv("catch_exceptions", false),
+    "True iff " GTEST_NAME_
+    " should catch exceptions and treat them as test failures.");
+
+GTEST_DEFINE_string_(
+    color,
+    internal::StringFromGTestEnv("color", "auto"),
+    "Whether to use colors in the output.  Valid values: yes, no, "
+    "and auto.  'auto' means to use colors if the output is "
+    "being sent to a terminal and the TERM environment variable "
+    "is set to xterm, xterm-color, xterm-256color, linux or cygwin.");
+
+GTEST_DEFINE_string_(
+    filter,
+    internal::StringFromGTestEnv("filter", kUniversalFilter),
+    "A colon-separated list of glob (not regex) patterns "
+    "for filtering the tests to run, optionally followed by a "
+    "'-' and a : separated list of negative patterns (tests to "
+    "exclude).  A test is run if it matches one of the positive "
+    "patterns and does not match any of the negative patterns.");
+
+GTEST_DEFINE_bool_(list_tests, false,
+                   "List all tests without running them.");
+
+GTEST_DEFINE_string_(
+    output,
+    internal::StringFromGTestEnv("output", ""),
+    "A format (currently must be \"xml\"), optionally followed "
+    "by a colon and an output file name or directory. A directory "
+    "is indicated by a trailing pathname separator. "
+    "Examples: \"xml:filename.xml\", \"xml::directoryname/\". "
+    "If a directory is specified, output files will be created "
+    "within that directory, with file-names based on the test "
+    "executable's name and, if necessary, made unique by adding "
+    "digits.");
+
+GTEST_DEFINE_bool_(
+    print_time,
+    internal::BoolFromGTestEnv("print_time", true),
+    "True iff " GTEST_NAME_
+    " should display elapsed time in text output.");
+
+GTEST_DEFINE_int32_(
+    random_seed,
+    internal::Int32FromGTestEnv("random_seed", 0),
+    "Random number seed to use when shuffling test orders.  Must be in range "
+    "[1, 99999], or 0 to use a seed based on the current time.");
+
+GTEST_DEFINE_int32_(
+    repeat,
+    internal::Int32FromGTestEnv("repeat", 1),
+    "How many times to repeat each test.  Specify a negative number "
+    "for repeating forever.  Useful for shaking out flaky tests.");
+
+GTEST_DEFINE_bool_(
+    show_internal_stack_frames, false,
+    "True iff " GTEST_NAME_ " should include internal stack frames when "
+    "printing test failure stack traces.");
+
+GTEST_DEFINE_bool_(
+    shuffle,
+    internal::BoolFromGTestEnv("shuffle", false),
+    "True iff " GTEST_NAME_
+    " should randomize tests' order on every run.");
+
+GTEST_DEFINE_int32_(
+    stack_trace_depth,
+    internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth),
+    "The maximum number of stack frames to print when an "
+    "assertion fails.  The valid range is 0 through 100, inclusive.");
+
+GTEST_DEFINE_bool_(
+    throw_on_failure,
+    internal::BoolFromGTestEnv("throw_on_failure", false),
+    "When this flag is specified, a failed assertion will throw an exception "
+    "if exceptions are enabled or exit the program with a non-zero code "
+    "otherwise.");
+
+namespace internal {
+
+// Generates a random number from [0, range), using a Linear
+// Congruential Generator (LCG).  Crashes if 'range' is 0 or greater
+// than kMaxRange.
+UInt32 Random::Generate(UInt32 range) {
+  // These constants are the same as are used in glibc's rand(3).
+  state_ = (1103515245U*state_ + 12345U) % kMaxRange;
+
+  GTEST_CHECK_(range > 0)
+      << "Cannot generate a number in the range [0, 0).";
+  GTEST_CHECK_(range <= kMaxRange)
+      << "Generation of a number in [0, " << range << ") was requested, "
+      << "but this can only generate numbers in [0, " << kMaxRange << ").";
+
+  // Converting via modulus introduces a bit of downward bias, but
+  // it's simple, and a linear congruential generator isn't too good
+  // to begin with.
+  return state_ % range;
+}
+
+// GTestIsInitialized() returns true iff the user has initialized
+// Google Test.  Useful for catching the user mistake of not initializing
+// Google Test before calling RUN_ALL_TESTS().
+//
+// A user must call testing::InitGoogleTest() to initialize Google
+// Test.  g_init_gtest_count is set to the number of times
+// InitGoogleTest() has been called.  We don't protect this variable
+// under a mutex as it is only accessed in the main thread.
+int g_init_gtest_count = 0;
+static bool GTestIsInitialized() { return g_init_gtest_count != 0; }
+
+// Iterates over a vector of TestCases, keeping a running sum of the
+// results of calling a given int-returning method on each.
+// Returns the sum.
+static int SumOverTestCaseList(const std::vector<TestCase*>& case_list,
+                               int (TestCase::*method)() const) {
+  int sum = 0;
+  for (size_t i = 0; i < case_list.size(); i++) {
+    sum += (case_list[i]->*method)();
+  }
+  return sum;
+}
+
+// Returns true iff the test case passed.
+static bool TestCasePassed(const TestCase* test_case) {
+  return test_case->should_run() && test_case->Passed();
+}
+
+// Returns true iff the test case failed.
+static bool TestCaseFailed(const TestCase* test_case) {
+  return test_case->should_run() && test_case->Failed();
+}
+
+// Returns true iff test_case contains at least one test that should
+// run.
+static bool ShouldRunTestCase(const TestCase* test_case) {
+  return test_case->should_run();
+}
+
+// AssertHelper constructor.
+AssertHelper::AssertHelper(TestPartResult::Type type,
+                           const char* file,
+                           int line,
+                           const char* message)
+    : data_(new AssertHelperData(type, file, line, message)) {
+}
+
+AssertHelper::~AssertHelper() {
+  delete data_;
+}
+
+// Message assignment, for assertion streaming support.
+void AssertHelper::operator=(const Message& message) const {
+  UnitTest::GetInstance()->
+    AddTestPartResult(data_->type, data_->file, data_->line,
+                      AppendUserMessage(data_->message, message),
+                      UnitTest::GetInstance()->impl()
+                      ->CurrentOsStackTraceExceptTop(1)
+                      // Skips the stack frame for this function itself.
+                      );  // NOLINT
+}
+
+// Mutex for linked pointers.
+GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex);
+
+// Application pathname gotten in InitGoogleTest.
+String g_executable_path;
+
+// Returns the current application's name, removing directory path if that
+// is present.
+FilePath GetCurrentExecutableName() {
+  FilePath result;
+
+#if GTEST_OS_WINDOWS
+  result.Set(FilePath(g_executable_path).RemoveExtension("exe"));
+#else
+  result.Set(FilePath(g_executable_path));
+#endif  // GTEST_OS_WINDOWS
+
+  return result.RemoveDirectoryName();
+}
+
+// Functions for processing the gtest_output flag.
+
+// Returns the output format, or "" for normal printed output.
+String UnitTestOptions::GetOutputFormat() {
+  const char* const gtest_output_flag = GTEST_FLAG(output).c_str();
+  if (gtest_output_flag == NULL) return String("");
+
+  const char* const colon = strchr(gtest_output_flag, ':');
+  return (colon == NULL) ?
+      String(gtest_output_flag) :
+      String(gtest_output_flag, colon - gtest_output_flag);
+}
+
+// Returns the name of the requested output file, or the default if none
+// was explicitly specified.
+String UnitTestOptions::GetAbsolutePathToOutputFile() {
+  const char* const gtest_output_flag = GTEST_FLAG(output).c_str();
+  if (gtest_output_flag == NULL)
+    return String("");
+
+  const char* const colon = strchr(gtest_output_flag, ':');
+  if (colon == NULL)
+    return String(internal::FilePath::ConcatPaths(
+               internal::FilePath(
+                   UnitTest::GetInstance()->original_working_dir()),
+               internal::FilePath(kDefaultOutputFile)).ToString() );
+
+  internal::FilePath output_name(colon + 1);
+  if (!output_name.IsAbsolutePath())
+    // TODO(wan@google.com): on Windows \some\path is not an absolute
+    // path (as its meaning depends on the current drive), yet the
+    // following logic for turning it into an absolute path is wrong.
+    // Fix it.
+    output_name = internal::FilePath::ConcatPaths(
+        internal::FilePath(UnitTest::GetInstance()->original_working_dir()),
+        internal::FilePath(colon + 1));
+
+  if (!output_name.IsDirectory())
+    return output_name.ToString();
+
+  internal::FilePath result(internal::FilePath::GenerateUniqueFileName(
+      output_name, internal::GetCurrentExecutableName(),
+      GetOutputFormat().c_str()));
+  return result.ToString();
+}
+
+// Returns true iff the wildcard pattern matches the string.  The
+// first ':' or '\0' character in pattern marks the end of it.
+//
+// This recursive algorithm isn't very efficient, but is clear and
+// works well enough for matching test names, which are short.
+bool UnitTestOptions::PatternMatchesString(const char *pattern,
+                                           const char *str) {
+  switch (*pattern) {
+    case '\0':
+    case ':':  // Either ':' or '\0' marks the end of the pattern.
+      return *str == '\0';
+    case '?':  // Matches any single character.
+      return *str != '\0' && PatternMatchesString(pattern + 1, str + 1);
+    case '*':  // Matches any string (possibly empty) of characters.
+      return (*str != '\0' && PatternMatchesString(pattern, str + 1)) ||
+          PatternMatchesString(pattern + 1, str);
+    default:  // Non-special character.  Matches itself.
+      return *pattern == *str &&
+          PatternMatchesString(pattern + 1, str + 1);
+  }
+}
+
+bool UnitTestOptions::MatchesFilter(const String& name, const char* filter) {
+  const char *cur_pattern = filter;
+  for (;;) {
+    if (PatternMatchesString(cur_pattern, name.c_str())) {
+      return true;
+    }
+
+    // Finds the next pattern in the filter.
+    cur_pattern = strchr(cur_pattern, ':');
+
+    // Returns if no more pattern can be found.
+    if (cur_pattern == NULL) {
+      return false;
+    }
+
+    // Skips the pattern separater (the ':' character).
+    cur_pattern++;
+  }
+}
+
+// TODO(keithray): move String function implementations to gtest-string.cc.
+
+// Returns true iff the user-specified filter matches the test case
+// name and the test name.
+bool UnitTestOptions::FilterMatchesTest(const String &test_case_name,
+                                        const String &test_name) {
+  const String& full_name = String::Format("%s.%s",
+                                           test_case_name.c_str(),
+                                           test_name.c_str());
+
+  // Split --gtest_filter at '-', if there is one, to separate into
+  // positive filter and negative filter portions
+  const char* const p = GTEST_FLAG(filter).c_str();
+  const char* const dash = strchr(p, '-');
+  String positive;
+  String negative;
+  if (dash == NULL) {
+    positive = GTEST_FLAG(filter).c_str();  // Whole string is a positive filter
+    negative = String("");
+  } else {
+    positive = String(p, dash - p);  // Everything up to the dash
+    negative = String(dash+1);       // Everything after the dash
+    if (positive.empty()) {
+      // Treat '-test1' as the same as '*-test1'
+      positive = kUniversalFilter;
+    }
+  }
+
+  // A filter is a colon-separated list of patterns.  It matches a
+  // test if any pattern in it matches the test.
+  return (MatchesFilter(full_name, positive.c_str()) &&
+          !MatchesFilter(full_name, negative.c_str()));
+}
+
+#if GTEST_OS_WINDOWS
+// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the
+// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise.
+// This function is useful as an __except condition.
+int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) {
+  // Google Test should handle an exception if:
+  //   1. the user wants it to, AND
+  //   2. this is not a breakpoint exception.
+  return (GTEST_FLAG(catch_exceptions) &&
+          exception_code != EXCEPTION_BREAKPOINT) ?
+      EXCEPTION_EXECUTE_HANDLER :
+      EXCEPTION_CONTINUE_SEARCH;
+}
+#endif  // GTEST_OS_WINDOWS
+
+}  // namespace internal
+
+// The c'tor sets this object as the test part result reporter used by
+// Google Test.  The 'result' parameter specifies where to report the
+// results. Intercepts only failures from the current thread.
+ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter(
+    TestPartResultArray* result)
+    : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD),
+      result_(result) {
+  Init();
+}
+
+// The c'tor sets this object as the test part result reporter used by
+// Google Test.  The 'result' parameter specifies where to report the
+// results.
+ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter(
+    InterceptMode intercept_mode, TestPartResultArray* result)
+    : intercept_mode_(intercept_mode),
+      result_(result) {
+  Init();
+}
+
+void ScopedFakeTestPartResultReporter::Init() {
+  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+  if (intercept_mode_ == INTERCEPT_ALL_THREADS) {
+    old_reporter_ = impl->GetGlobalTestPartResultReporter();
+    impl->SetGlobalTestPartResultReporter(this);
+  } else {
+    old_reporter_ = impl->GetTestPartResultReporterForCurrentThread();
+    impl->SetTestPartResultReporterForCurrentThread(this);
+  }
+}
+
+// The d'tor restores the test part result reporter used by Google Test
+// before.
+ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() {
+  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+  if (intercept_mode_ == INTERCEPT_ALL_THREADS) {
+    impl->SetGlobalTestPartResultReporter(old_reporter_);
+  } else {
+    impl->SetTestPartResultReporterForCurrentThread(old_reporter_);
+  }
+}
+
+// Increments the test part result count and remembers the result.
+// This method is from the TestPartResultReporterInterface interface.
+void ScopedFakeTestPartResultReporter::ReportTestPartResult(
+    const TestPartResult& result) {
+  result_->Append(result);
+}
+
+namespace internal {
+
+// Returns the type ID of ::testing::Test.  We should always call this
+// instead of GetTypeId< ::testing::Test>() to get the type ID of
+// testing::Test.  This is to work around a suspected linker bug when
+// using Google Test as a framework on Mac OS X.  The bug causes
+// GetTypeId< ::testing::Test>() to return different values depending
+// on whether the call is from the Google Test framework itself or
+// from user test code.  GetTestTypeId() is guaranteed to always
+// return the same value, as it always calls GetTypeId<>() from the
+// gtest.cc, which is within the Google Test framework.
+TypeId GetTestTypeId() {
+  return GetTypeId<Test>();
+}
+
+// The value of GetTestTypeId() as seen from within the Google Test
+// library.  This is solely for testing GetTestTypeId().
+const TypeId kTestTypeIdInGoogleTest = GetTestTypeId();
+
+// This predicate-formatter checks that 'results' contains a test part
+// failure of the given type and that the failure message contains the
+// given substring.
+AssertionResult HasOneFailure(const char* /* results_expr */,
+                              const char* /* type_expr */,
+                              const char* /* substr_expr */,
+                              const TestPartResultArray& results,
+                              TestPartResult::Type type,
+                              const char* substr) {
+  const String expected(type == TestPartResult::kFatalFailure ?
+                        "1 fatal failure" :
+                        "1 non-fatal failure");
+  Message msg;
+  if (results.size() != 1) {
+    msg << "Expected: " << expected << "\n"
+        << "  Actual: " << results.size() << " failures";
+    for (int i = 0; i < results.size(); i++) {
+      msg << "\n" << results.GetTestPartResult(i);
+    }
+    return AssertionFailure(msg);
+  }
+
+  const TestPartResult& r = results.GetTestPartResult(0);
+  if (r.type() != type) {
+    msg << "Expected: " << expected << "\n"
+        << "  Actual:\n"
+        << r;
+    return AssertionFailure(msg);
+  }
+
+  if (strstr(r.message(), substr) == NULL) {
+    msg << "Expected: " << expected << " containing \""
+        << substr << "\"\n"
+        << "  Actual:\n"
+        << r;
+    return AssertionFailure(msg);
+  }
+
+  return AssertionSuccess();
+}
+
+// The constructor of SingleFailureChecker remembers where to look up
+// test part results, what type of failure we expect, and what
+// substring the failure message should contain.
+SingleFailureChecker:: SingleFailureChecker(
+    const TestPartResultArray* results,
+    TestPartResult::Type type,
+    const char* substr)
+    : results_(results),
+      type_(type),
+      substr_(substr) {}
+
+// The destructor of SingleFailureChecker verifies that the given
+// TestPartResultArray contains exactly one failure that has the given
+// type and contains the given substring.  If that's not the case, a
+// non-fatal failure will be generated.
+SingleFailureChecker::~SingleFailureChecker() {
+  EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_.c_str());
+}
+
+DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter(
+    UnitTestImpl* unit_test) : unit_test_(unit_test) {}
+
+void DefaultGlobalTestPartResultReporter::ReportTestPartResult(
+    const TestPartResult& result) {
+  unit_test_->current_test_result()->AddTestPartResult(result);
+  unit_test_->listeners()->repeater()->OnTestPartResult(result);
+}
+
+DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter(
+    UnitTestImpl* unit_test) : unit_test_(unit_test) {}
+
+void DefaultPerThreadTestPartResultReporter::ReportTestPartResult(
+    const TestPartResult& result) {
+  unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result);
+}
+
+// Returns the global test part result reporter.
+TestPartResultReporterInterface*
+UnitTestImpl::GetGlobalTestPartResultReporter() {
+  internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
+  return global_test_part_result_repoter_;
+}
+
+// Sets the global test part result reporter.
+void UnitTestImpl::SetGlobalTestPartResultReporter(
+    TestPartResultReporterInterface* reporter) {
+  internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
+  global_test_part_result_repoter_ = reporter;
+}
+
+// Returns the test part result reporter for the current thread.
+TestPartResultReporterInterface*
+UnitTestImpl::GetTestPartResultReporterForCurrentThread() {
+  return per_thread_test_part_result_reporter_.get();
+}
+
+// Sets the test part result reporter for the current thread.
+void UnitTestImpl::SetTestPartResultReporterForCurrentThread(
+    TestPartResultReporterInterface* reporter) {
+  per_thread_test_part_result_reporter_.set(reporter);
+}
+
+// Gets the number of successful test cases.
+int UnitTestImpl::successful_test_case_count() const {
+  return CountIf(test_cases_, TestCasePassed);
+}
+
+// Gets the number of failed test cases.
+int UnitTestImpl::failed_test_case_count() const {
+  return CountIf(test_cases_, TestCaseFailed);
+}
+
+// Gets the number of all test cases.
+int UnitTestImpl::total_test_case_count() const {
+  return static_cast<int>(test_cases_.size());
+}
+
+// Gets the number of all test cases that contain at least one test
+// that should run.
+int UnitTestImpl::test_case_to_run_count() const {
+  return CountIf(test_cases_, ShouldRunTestCase);
+}
+
+// Gets the number of successful tests.
+int UnitTestImpl::successful_test_count() const {
+  return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count);
+}
+
+// Gets the number of failed tests.
+int UnitTestImpl::failed_test_count() const {
+  return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count);
+}
+
+// Gets the number of disabled tests.
+int UnitTestImpl::disabled_test_count() const {
+  return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count);
+}
+
+// Gets the number of all tests.
+int UnitTestImpl::total_test_count() const {
+  return SumOverTestCaseList(test_cases_, &TestCase::total_test_count);
+}
+
+// Gets the number of tests that should run.
+int UnitTestImpl::test_to_run_count() const {
+  return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count);
+}
+
+// Returns the current OS stack trace as a String.
+//
+// The maximum number of stack frames to be included is specified by
+// the gtest_stack_trace_depth flag.  The skip_count parameter
+// specifies the number of top frames to be skipped, which doesn't
+// count against the number of frames to be included.
+//
+// For example, if Foo() calls Bar(), which in turn calls
+// CurrentOsStackTraceExceptTop(1), Foo() will be included in the
+// trace but Bar() and CurrentOsStackTraceExceptTop() won't.
+String UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) {
+  (void)skip_count;
+  return String("");
+}
+
+// Returns the current time in milliseconds.
+TimeInMillis GetTimeInMillis() {
+#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__)
+  // Difference between 1970-01-01 and 1601-01-01 in milliseconds.
+  // http://analogous.blogspot.com/2005/04/epoch.html
+  const TimeInMillis kJavaEpochToWinFileTimeDelta =
+    static_cast<TimeInMillis>(116444736UL) * 100000UL;
+  const DWORD kTenthMicrosInMilliSecond = 10000;
+
+  SYSTEMTIME now_systime;
+  FILETIME now_filetime;
+  ULARGE_INTEGER now_int64;
+  // TODO(kenton@google.com): Shouldn't this just use
+  //   GetSystemTimeAsFileTime()?
+  GetSystemTime(&now_systime);
+  if (SystemTimeToFileTime(&now_systime, &now_filetime)) {
+    now_int64.LowPart = now_filetime.dwLowDateTime;
+    now_int64.HighPart = now_filetime.dwHighDateTime;
+    now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) -
+      kJavaEpochToWinFileTimeDelta;
+    return now_int64.QuadPart;
+  }
+  return 0;
+#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_
+  __timeb64 now;
+#ifdef _MSC_VER
+  // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996
+  // (deprecated function) there.
+  // TODO(kenton@google.com): Use GetTickCount()?  Or use
+  //   SystemTimeToFileTime()
+#pragma warning(push)          // Saves the current warning state.
+#pragma warning(disable:4996)  // Temporarily disables warning 4996.
+  _ftime64(&now);
+#pragma warning(pop)           // Restores the warning state.
+#else
+  _ftime64(&now);
+#endif  // _MSC_VER
+  return static_cast<TimeInMillis>(now.time) * 1000 + now.millitm;
+#elif GTEST_HAS_GETTIMEOFDAY_
+  struct timeval now;
+  gettimeofday(&now, NULL);
+  return static_cast<TimeInMillis>(now.tv_sec) * 1000 + now.tv_usec / 1000;
+#else
+#error "Don't know how to get the current time on your system."
+#endif
+}
+
+// Utilities
+
+// class String
+
+// Returns the input enclosed in double quotes if it's not NULL;
+// otherwise returns "(null)".  For example, "\"Hello\"" is returned
+// for input "Hello".
+//
+// This is useful for printing a C string in the syntax of a literal.
+//
+// Known issue: escape sequences are not handled yet.
+String String::ShowCStringQuoted(const char* c_str) {
+  return c_str ? String::Format("\"%s\"", c_str) : String("(null)");
+}
+
+// Copies at most length characters from str into a newly-allocated
+// piece of memory of size length+1.  The memory is allocated with new[].
+// A terminating null byte is written to the memory, and a pointer to it
+// is returned.  If str is NULL, NULL is returned.
+static char* CloneString(const char* str, size_t length) {
+  if (str == NULL) {
+    return NULL;
+  } else {
+    char* const clone = new char[length + 1];
+    posix::StrNCpy(clone, str, length);
+    clone[length] = '\0';
+    return clone;
+  }
+}
+
+// Clones a 0-terminated C string, allocating memory using new.  The
+// caller is responsible for deleting[] the return value.  Returns the
+// cloned string, or NULL if the input is NULL.
+const char * String::CloneCString(const char* c_str) {
+  return (c_str == NULL) ?
+                    NULL : CloneString(c_str, strlen(c_str));
+}
+
+#if GTEST_OS_WINDOWS_MOBILE
+// Creates a UTF-16 wide string from the given ANSI string, allocating
+// memory using new. The caller is responsible for deleting the return
+// value using delete[]. Returns the wide string, or NULL if the
+// input is NULL.
+LPCWSTR String::AnsiToUtf16(const char* ansi) {
+  if (!ansi) return NULL;
+  const int length = strlen(ansi);
+  const int unicode_length =
+      MultiByteToWideChar(CP_ACP, 0, ansi, length,
+                          NULL, 0);
+  WCHAR* unicode = new WCHAR[unicode_length + 1];
+  MultiByteToWideChar(CP_ACP, 0, ansi, length,
+                      unicode, unicode_length);
+  unicode[unicode_length] = 0;
+  return unicode;
+}
+
+// Creates an ANSI string from the given wide string, allocating
+// memory using new. The caller is responsible for deleting the return
+// value using delete[]. Returns the ANSI string, or NULL if the
+// input is NULL.
+const char* String::Utf16ToAnsi(LPCWSTR utf16_str)  {
+  if (!utf16_str) return NULL;
+  const int ansi_length =
+      WideCharToMultiByte(CP_ACP, 0, utf16_str, -1,
+                          NULL, 0, NULL, NULL);
+  char* ansi = new char[ansi_length + 1];
+  WideCharToMultiByte(CP_ACP, 0, utf16_str, -1,
+                      ansi, ansi_length, NULL, NULL);
+  ansi[ansi_length] = 0;
+  return ansi;
+}
+
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+// Compares two C strings.  Returns true iff they have the same content.
+//
+// Unlike strcmp(), this function can handle NULL argument(s).  A NULL
+// C string is considered different to any non-NULL C string,
+// including the empty string.
+bool String::CStringEquals(const char * lhs, const char * rhs) {
+  if ( lhs == NULL ) return rhs == NULL;
+
+  if ( rhs == NULL ) return false;
+
+  return strcmp(lhs, rhs) == 0;
+}
+
+#if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING
+
+// Converts an array of wide chars to a narrow string using the UTF-8
+// encoding, and streams the result to the given Message object.
+static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length,
+                                     Message* msg) {
+  // TODO(wan): consider allowing a testing::String object to
+  // contain '\0'.  This will make it behave more like std::string,
+  // and will allow ToUtf8String() to return the correct encoding
+  // for '\0' s.t. we can get rid of the conditional here (and in
+  // several other places).
+  for (size_t i = 0; i != length; ) {  // NOLINT
+    if (wstr[i] != L'\0') {
+      *msg << WideStringToUtf8(wstr + i, static_cast<int>(length - i));
+      while (i != length && wstr[i] != L'\0')
+        i++;
+    } else {
+      *msg << '\0';
+      i++;
+    }
+  }
+}
+
+#endif  // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING
+
+}  // namespace internal
+
+#if GTEST_HAS_STD_WSTRING
+// Converts the given wide string to a narrow string using the UTF-8
+// encoding, and streams the result to this Message object.
+Message& Message::operator <<(const ::std::wstring& wstr) {
+  internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this);
+  return *this;
+}
+#endif  // GTEST_HAS_STD_WSTRING
+
+#if GTEST_HAS_GLOBAL_WSTRING
+// Converts the given wide string to a narrow string using the UTF-8
+// encoding, and streams the result to this Message object.
+Message& Message::operator <<(const ::wstring& wstr) {
+  internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this);
+  return *this;
+}
+#endif  // GTEST_HAS_GLOBAL_WSTRING
+
+namespace internal {
+
+// Formats a value to be used in a failure message.
+
+// For a char value, we print it as a C++ char literal and as an
+// unsigned integer (both in decimal and in hexadecimal).
+String FormatForFailureMessage(char ch) {
+  const unsigned int ch_as_uint = ch;
+  // A String object cannot contain '\0', so we print "\\0" when ch is
+  // '\0'.
+  return String::Format("'%s' (%u, 0x%X)",
+                        ch ? String::Format("%c", ch).c_str() : "\\0",
+                        ch_as_uint, ch_as_uint);
+}
+
+// For a wchar_t value, we print it as a C++ wchar_t literal and as an
+// unsigned integer (both in decimal and in hexidecimal).
+String FormatForFailureMessage(wchar_t wchar) {
+  // The C++ standard doesn't specify the exact size of the wchar_t
+  // type.  It just says that it shall have the same size as another
+  // integral type, called its underlying type.
+  //
+  // Therefore, in order to print a wchar_t value in the numeric form,
+  // we first convert it to the largest integral type (UInt64) and
+  // then print the converted value.
+  //
+  // We use streaming to print the value as "%llu" doesn't work
+  // correctly with MSVC 7.1.
+  const UInt64 wchar_as_uint64 = wchar;
+  Message msg;
+  // A String object cannot contain '\0', so we print "\\0" when wchar is
+  // L'\0'.
+  char buffer[32];  // CodePointToUtf8 requires a buffer that big.
+  msg << "L'"
+      << (wchar ? CodePointToUtf8(static_cast<UInt32>(wchar), buffer) : "\\0")
+      << "' (" << wchar_as_uint64 << ", 0x" << ::std::setbase(16)
+      << wchar_as_uint64 << ")";
+  return msg.GetString();
+}
+
+}  // namespace internal
+
+// AssertionResult constructors.
+// Used in EXPECT_TRUE/FALSE(assertion_result).
+AssertionResult::AssertionResult(const AssertionResult& other)
+    : success_(other.success_),
+      message_(other.message_.get() != NULL ?
+               new internal::String(*other.message_) :
+               static_cast<internal::String*>(NULL)) {
+}
+
+// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
+AssertionResult AssertionResult::operator!() const {
+  AssertionResult negation(!success_);
+  if (message_.get() != NULL)
+    negation << *message_;
+  return negation;
+}
+
+// Makes a successful assertion result.
+AssertionResult AssertionSuccess() {
+  return AssertionResult(true);
+}
+
+// Makes a failed assertion result.
+AssertionResult AssertionFailure() {
+  return AssertionResult(false);
+}
+
+// Makes a failed assertion result with the given failure message.
+// Deprecated; use AssertionFailure() << message.
+AssertionResult AssertionFailure(const Message& message) {
+  return AssertionFailure() << message;
+}
+
+namespace internal {
+
+// Constructs and returns the message for an equality assertion
+// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.
+//
+// The first four parameters are the expressions used in the assertion
+// and their values, as strings.  For example, for ASSERT_EQ(foo, bar)
+// where foo is 5 and bar is 6, we have:
+//
+//   expected_expression: "foo"
+//   actual_expression:   "bar"
+//   expected_value:      "5"
+//   actual_value:        "6"
+//
+// The ignoring_case parameter is true iff the assertion is a
+// *_STRCASEEQ*.  When it's true, the string " (ignoring case)" will
+// be inserted into the message.
+AssertionResult EqFailure(const char* expected_expression,
+                          const char* actual_expression,
+                          const String& expected_value,
+                          const String& actual_value,
+                          bool ignoring_case) {
+  Message msg;
+  msg << "Value of: " << actual_expression;
+  if (actual_value != actual_expression) {
+    msg << "\n  Actual: " << actual_value;
+  }
+
+  msg << "\nExpected: " << expected_expression;
+  if (ignoring_case) {
+    msg << " (ignoring case)";
+  }
+  if (expected_value != expected_expression) {
+    msg << "\nWhich is: " << expected_value;
+  }
+
+  return AssertionFailure(msg);
+}
+
+// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.
+String GetBoolAssertionFailureMessage(const AssertionResult& assertion_result,
+                                      const char* expression_text,
+                                      const char* actual_predicate_value,
+                                      const char* expected_predicate_value) {
+  const char* actual_message = assertion_result.message();
+  Message msg;
+  msg << "Value of: " << expression_text
+      << "\n  Actual: " << actual_predicate_value;
+  if (actual_message[0] != '\0')
+    msg << " (" << actual_message << ")";
+  msg << "\nExpected: " << expected_predicate_value;
+  return msg.GetString();
+}
+
+// Helper function for implementing ASSERT_NEAR.
+AssertionResult DoubleNearPredFormat(const char* expr1,
+                                     const char* expr2,
+                                     const char* abs_error_expr,
+                                     double val1,
+                                     double val2,
+                                     double abs_error) {
+  const double diff = fabs(val1 - val2);
+  if (diff <= abs_error) return AssertionSuccess();
+
+  // TODO(wan): do not print the value of an expression if it's
+  // already a literal.
+  Message msg;
+  msg << "The difference between " << expr1 << " and " << expr2
+      << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n"
+      << expr1 << " evaluates to " << val1 << ",\n"
+      << expr2 << " evaluates to " << val2 << ", and\n"
+      << abs_error_expr << " evaluates to " << abs_error << ".";
+  return AssertionFailure(msg);
+}
+
+
+// Helper template for implementing FloatLE() and DoubleLE().
+template <typename RawType>
+AssertionResult FloatingPointLE(const char* expr1,
+                                const char* expr2,
+                                RawType val1,
+                                RawType val2) {
+  // Returns success if val1 is less than val2,
+  if (val1 < val2) {
+    return AssertionSuccess();
+  }
+
+  // or if val1 is almost equal to val2.
+  const FloatingPoint<RawType> lhs(val1), rhs(val2);
+  if (lhs.AlmostEquals(rhs)) {
+    return AssertionSuccess();
+  }
+
+  // Note that the above two checks will both fail if either val1 or
+  // val2 is NaN, as the IEEE floating-point standard requires that
+  // any predicate involving a NaN must return false.
+
+  StrStream val1_ss;
+  val1_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
+          << val1;
+
+  StrStream val2_ss;
+  val2_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
+          << val2;
+
+  Message msg;
+  msg << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n"
+      << "  Actual: " << StrStreamToString(&val1_ss) << " vs "
+      << StrStreamToString(&val2_ss);
+
+  return AssertionFailure(msg);
+}
+
+}  // namespace internal
+
+// Asserts that val1 is less than, or almost equal to, val2.  Fails
+// otherwise.  In particular, it fails if either val1 or val2 is NaN.
+AssertionResult FloatLE(const char* expr1, const char* expr2,
+                        float val1, float val2) {
+  return internal::FloatingPointLE<float>(expr1, expr2, val1, val2);
+}
+
+// Asserts that val1 is less than, or almost equal to, val2.  Fails
+// otherwise.  In particular, it fails if either val1 or val2 is NaN.
+AssertionResult DoubleLE(const char* expr1, const char* expr2,
+                         double val1, double val2) {
+  return internal::FloatingPointLE<double>(expr1, expr2, val1, val2);
+}
+
+namespace internal {
+
+// The helper function for {ASSERT|EXPECT}_EQ with int or enum
+// arguments.
+AssertionResult CmpHelperEQ(const char* expected_expression,
+                            const char* actual_expression,
+                            BiggestInt expected,
+                            BiggestInt actual) {
+  if (expected == actual) {
+    return AssertionSuccess();
+  }
+
+  return EqFailure(expected_expression,
+                   actual_expression,
+                   FormatForComparisonFailureMessage(expected, actual),
+                   FormatForComparisonFailureMessage(actual, expected),
+                   false);
+}
+
+// A macro for implementing the helper functions needed to implement
+// ASSERT_?? and EXPECT_?? with integer or enum arguments.  It is here
+// just to avoid copy-and-paste of similar code.
+#define GTEST_IMPL_CMP_HELPER_(op_name, op)\
+AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \
+                                   BiggestInt val1, BiggestInt val2) {\
+  if (val1 op val2) {\
+    return AssertionSuccess();\
+  } else {\
+    Message msg;\
+    msg << "Expected: (" << expr1 << ") " #op " (" << expr2\
+        << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\
+        << " vs " << FormatForComparisonFailureMessage(val2, val1);\
+    return AssertionFailure(msg);\
+  }\
+}
+
+// Implements the helper function for {ASSERT|EXPECT}_NE with int or
+// enum arguments.
+GTEST_IMPL_CMP_HELPER_(NE, !=)
+// Implements the helper function for {ASSERT|EXPECT}_LE with int or
+// enum arguments.
+GTEST_IMPL_CMP_HELPER_(LE, <=)
+// Implements the helper function for {ASSERT|EXPECT}_LT with int or
+// enum arguments.
+GTEST_IMPL_CMP_HELPER_(LT, < )
+// Implements the helper function for {ASSERT|EXPECT}_GE with int or
+// enum arguments.
+GTEST_IMPL_CMP_HELPER_(GE, >=)
+// Implements the helper function for {ASSERT|EXPECT}_GT with int or
+// enum arguments.
+GTEST_IMPL_CMP_HELPER_(GT, > )
+
+#undef GTEST_IMPL_CMP_HELPER_
+
+// The helper function for {ASSERT|EXPECT}_STREQ.
+AssertionResult CmpHelperSTREQ(const char* expected_expression,
+                               const char* actual_expression,
+                               const char* expected,
+                               const char* actual) {
+  if (String::CStringEquals(expected, actual)) {
+    return AssertionSuccess();
+  }
+
+  return EqFailure(expected_expression,
+                   actual_expression,
+                   String::ShowCStringQuoted(expected),
+                   String::ShowCStringQuoted(actual),
+                   false);
+}
+
+// The helper function for {ASSERT|EXPECT}_STRCASEEQ.
+AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression,
+                                   const char* actual_expression,
+                                   const char* expected,
+                                   const char* actual) {
+  if (String::CaseInsensitiveCStringEquals(expected, actual)) {
+    return AssertionSuccess();
+  }
+
+  return EqFailure(expected_expression,
+                   actual_expression,
+                   String::ShowCStringQuoted(expected),
+                   String::ShowCStringQuoted(actual),
+                   true);
+}
+
+// The helper function for {ASSERT|EXPECT}_STRNE.
+AssertionResult CmpHelperSTRNE(const char* s1_expression,
+                               const char* s2_expression,
+                               const char* s1,
+                               const char* s2) {
+  if (!String::CStringEquals(s1, s2)) {
+    return AssertionSuccess();
+  } else {
+    Message msg;
+    msg << "Expected: (" << s1_expression << ") != ("
+        << s2_expression << "), actual: \""
+        << s1 << "\" vs \"" << s2 << "\"";
+    return AssertionFailure(msg);
+  }
+}
+
+// The helper function for {ASSERT|EXPECT}_STRCASENE.
+AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
+                                   const char* s2_expression,
+                                   const char* s1,
+                                   const char* s2) {
+  if (!String::CaseInsensitiveCStringEquals(s1, s2)) {
+    return AssertionSuccess();
+  } else {
+    Message msg;
+    msg << "Expected: (" << s1_expression << ") != ("
+        << s2_expression << ") (ignoring case), actual: \""
+        << s1 << "\" vs \"" << s2 << "\"";
+    return AssertionFailure(msg);
+  }
+}
+
+}  // namespace internal
+
+namespace {
+
+// Helper functions for implementing IsSubString() and IsNotSubstring().
+
+// This group of overloaded functions return true iff needle is a
+// substring of haystack.  NULL is considered a substring of itself
+// only.
+
+bool IsSubstringPred(const char* needle, const char* haystack) {
+  if (needle == NULL || haystack == NULL)
+    return needle == haystack;
+
+  return strstr(haystack, needle) != NULL;
+}
+
+bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) {
+  if (needle == NULL || haystack == NULL)
+    return needle == haystack;
+
+  return wcsstr(haystack, needle) != NULL;
+}
+
+// StringType here can be either ::std::string or ::std::wstring.
+template <typename StringType>
+bool IsSubstringPred(const StringType& needle,
+                     const StringType& haystack) {
+  return haystack.find(needle) != StringType::npos;
+}
+
+// This function implements either IsSubstring() or IsNotSubstring(),
+// depending on the value of the expected_to_be_substring parameter.
+// StringType here can be const char*, const wchar_t*, ::std::string,
+// or ::std::wstring.
+template <typename StringType>
+AssertionResult IsSubstringImpl(
+    bool expected_to_be_substring,
+    const char* needle_expr, const char* haystack_expr,
+    const StringType& needle, const StringType& haystack) {
+  if (IsSubstringPred(needle, haystack) == expected_to_be_substring)
+    return AssertionSuccess();
+
+  const bool is_wide_string = sizeof(needle[0]) > 1;
+  const char* const begin_string_quote = is_wide_string ? "L\"" : "\"";
+  return AssertionFailure(
+      Message()
+      << "Value of: " << needle_expr << "\n"
+      << "  Actual: " << begin_string_quote << needle << "\"\n"
+      << "Expected: " << (expected_to_be_substring ? "" : "not ")
+      << "a substring of " << haystack_expr << "\n"
+      << "Which is: " << begin_string_quote << haystack << "\"");
+}
+
+}  // namespace
+
+// IsSubstring() and IsNotSubstring() check whether needle is a
+// substring of haystack (NULL is considered a substring of itself
+// only), and return an appropriate error message when they fail.
+
+AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const char* needle, const char* haystack) {
+  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const wchar_t* needle, const wchar_t* haystack) {
+  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const char* needle, const char* haystack) {
+  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const wchar_t* needle, const wchar_t* haystack) {
+  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::string& needle, const ::std::string& haystack) {
+  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::string& needle, const ::std::string& haystack) {
+  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
+}
+
+#if GTEST_HAS_STD_WSTRING
+AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::wstring& needle, const ::std::wstring& haystack) {
+  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::wstring& needle, const ::std::wstring& haystack) {
+  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
+}
+#endif  // GTEST_HAS_STD_WSTRING
+
+namespace internal {
+
+#if GTEST_OS_WINDOWS
+
+namespace {
+
+// Helper function for IsHRESULT{SuccessFailure} predicates
+AssertionResult HRESULTFailureHelper(const char* expr,
+                                     const char* expected,
+                                     long hr) {  // NOLINT
+#if GTEST_OS_WINDOWS_MOBILE
+  // Windows CE doesn't support FormatMessage.
+  const char error_text[] = "";
+#else
+  // Looks up the human-readable system message for the HRESULT code
+  // and since we're not passing any params to FormatMessage, we don't
+  // want inserts expanded.
+  const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM |
+                       FORMAT_MESSAGE_IGNORE_INSERTS;
+  const DWORD kBufSize = 4096;  // String::Format can't exceed this length.
+  // Gets the system's human readable message string for this HRESULT.
+  char error_text[kBufSize] = { '\0' };
+  DWORD message_length = ::FormatMessageA(kFlags,
+                                          0,  // no source, we're asking system
+                                          hr,  // the error
+                                          0,  // no line width restrictions
+                                          error_text,  // output buffer
+                                          kBufSize,  // buf size
+                                          NULL);  // no arguments for inserts
+  // Trims tailing white space (FormatMessage leaves a trailing cr-lf)
+  for (; message_length && isspace(error_text[message_length - 1]);
+          --message_length) {
+    error_text[message_length - 1] = '\0';
+  }
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+  const String error_hex(String::Format("0x%08X ", hr));
+  Message msg;
+  msg << "Expected: " << expr << " " << expected << ".\n"
+      << "  Actual: " << error_hex << error_text << "\n";
+
+  return ::testing::AssertionFailure(msg);
+}
+
+}  // namespace
+
+AssertionResult IsHRESULTSuccess(const char* expr, long hr) {  // NOLINT
+  if (SUCCEEDED(hr)) {
+    return AssertionSuccess();
+  }
+  return HRESULTFailureHelper(expr, "succeeds", hr);
+}
+
+AssertionResult IsHRESULTFailure(const char* expr, long hr) {  // NOLINT
+  if (FAILED(hr)) {
+    return AssertionSuccess();
+  }
+  return HRESULTFailureHelper(expr, "fails", hr);
+}
+
+#endif  // GTEST_OS_WINDOWS
+
+// Utility functions for encoding Unicode text (wide strings) in
+// UTF-8.
+
+// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8
+// like this:
+//
+// Code-point length   Encoding
+//   0 -  7 bits       0xxxxxxx
+//   8 - 11 bits       110xxxxx 10xxxxxx
+//  12 - 16 bits       1110xxxx 10xxxxxx 10xxxxxx
+//  17 - 21 bits       11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+
+// The maximum code-point a one-byte UTF-8 sequence can represent.
+const UInt32 kMaxCodePoint1 = (static_cast<UInt32>(1) <<  7) - 1;
+
+// The maximum code-point a two-byte UTF-8 sequence can represent.
+const UInt32 kMaxCodePoint2 = (static_cast<UInt32>(1) << (5 + 6)) - 1;
+
+// The maximum code-point a three-byte UTF-8 sequence can represent.
+const UInt32 kMaxCodePoint3 = (static_cast<UInt32>(1) << (4 + 2*6)) - 1;
+
+// The maximum code-point a four-byte UTF-8 sequence can represent.
+const UInt32 kMaxCodePoint4 = (static_cast<UInt32>(1) << (3 + 3*6)) - 1;
+
+// Chops off the n lowest bits from a bit pattern.  Returns the n
+// lowest bits.  As a side effect, the original bit pattern will be
+// shifted to the right by n bits.
+inline UInt32 ChopLowBits(UInt32* bits, int n) {
+  const UInt32 low_bits = *bits & ((static_cast<UInt32>(1) << n) - 1);
+  *bits >>= n;
+  return low_bits;
+}
+
+// Converts a Unicode code point to a narrow string in UTF-8 encoding.
+// code_point parameter is of type UInt32 because wchar_t may not be
+// wide enough to contain a code point.
+// The output buffer str must containt at least 32 characters.
+// The function returns the address of the output buffer.
+// If the code_point is not a valid Unicode code point
+// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output
+// as '(Invalid Unicode 0xXXXXXXXX)'.
+char* CodePointToUtf8(UInt32 code_point, char* str) {
+  if (code_point <= kMaxCodePoint1) {
+    str[1] = '\0';
+    str[0] = static_cast<char>(code_point);                          // 0xxxxxxx
+  } else if (code_point <= kMaxCodePoint2) {
+    str[2] = '\0';
+    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[0] = static_cast<char>(0xC0 | code_point);                   // 110xxxxx
+  } else if (code_point <= kMaxCodePoint3) {
+    str[3] = '\0';
+    str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[0] = static_cast<char>(0xE0 | code_point);                   // 1110xxxx
+  } else if (code_point <= kMaxCodePoint4) {
+    str[4] = '\0';
+    str[3] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[0] = static_cast<char>(0xF0 | code_point);                   // 11110xxx
+  } else {
+    // The longest string String::Format can produce when invoked
+    // with these parameters is 28 character long (not including
+    // the terminating nul character). We are asking for 32 character
+    // buffer just in case. This is also enough for strncpy to
+    // null-terminate the destination string.
+    posix::StrNCpy(
+        str, String::Format("(Invalid Unicode 0x%X)", code_point).c_str(), 32);
+    str[31] = '\0';  // Makes sure no change in the format to strncpy leaves
+                     // the result unterminated.
+  }
+  return str;
+}
+
+// The following two functions only make sense if the the system
+// uses UTF-16 for wide string encoding. All supported systems
+// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16.
+
+// Determines if the arguments constitute UTF-16 surrogate pair
+// and thus should be combined into a single Unicode code point
+// using CreateCodePointFromUtf16SurrogatePair.
+inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) {
+  return sizeof(wchar_t) == 2 &&
+      (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00;
+}
+
+// Creates a Unicode code point from UTF16 surrogate pair.
+inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first,
+                                                    wchar_t second) {
+  const UInt32 mask = (1 << 10) - 1;
+  return (sizeof(wchar_t) == 2) ?
+      (((first & mask) << 10) | (second & mask)) + 0x10000 :
+      // This function should not be called when the condition is
+      // false, but we provide a sensible default in case it is.
+      static_cast<UInt32>(first);
+}
+
+// Converts a wide string to a narrow string in UTF-8 encoding.
+// The wide string is assumed to have the following encoding:
+//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS)
+//   UTF-32 if sizeof(wchar_t) == 4 (on Linux)
+// Parameter str points to a null-terminated wide string.
+// Parameter num_chars may additionally limit the number
+// of wchar_t characters processed. -1 is used when the entire string
+// should be processed.
+// If the string contains code points that are not valid Unicode code points
+// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output
+// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding
+// and contains invalid UTF-16 surrogate pairs, values in those pairs
+// will be encoded as individual Unicode characters from Basic Normal Plane.
+String WideStringToUtf8(const wchar_t* str, int num_chars) {
+  if (num_chars == -1)
+    num_chars = static_cast<int>(wcslen(str));
+
+  StrStream stream;
+  for (int i = 0; i < num_chars; ++i) {
+    UInt32 unicode_code_point;
+
+    if (str[i] == L'\0') {
+      break;
+    } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) {
+      unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i],
+                                                                 str[i + 1]);
+      i++;
+    } else {
+      unicode_code_point = static_cast<UInt32>(str[i]);
+    }
+
+    char buffer[32];  // CodePointToUtf8 requires a buffer this big.
+    stream << CodePointToUtf8(unicode_code_point, buffer);
+  }
+  return StrStreamToString(&stream);
+}
+
+// Converts a wide C string to a String using the UTF-8 encoding.
+// NULL will be converted to "(null)".
+String String::ShowWideCString(const wchar_t * wide_c_str) {
+  if (wide_c_str == NULL) return String("(null)");
+
+  return String(internal::WideStringToUtf8(wide_c_str, -1).c_str());
+}
+
+// Similar to ShowWideCString(), except that this function encloses
+// the converted string in double quotes.
+String String::ShowWideCStringQuoted(const wchar_t* wide_c_str) {
+  if (wide_c_str == NULL) return String("(null)");
+
+  return String::Format("L\"%s\"",
+                        String::ShowWideCString(wide_c_str).c_str());
+}
+
+// Compares two wide C strings.  Returns true iff they have the same
+// content.
+//
+// Unlike wcscmp(), this function can handle NULL argument(s).  A NULL
+// C string is considered different to any non-NULL C string,
+// including the empty string.
+bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) {
+  if (lhs == NULL) return rhs == NULL;
+
+  if (rhs == NULL) return false;
+
+  return wcscmp(lhs, rhs) == 0;
+}
+
+// Helper function for *_STREQ on wide strings.
+AssertionResult CmpHelperSTREQ(const char* expected_expression,
+                               const char* actual_expression,
+                               const wchar_t* expected,
+                               const wchar_t* actual) {
+  if (String::WideCStringEquals(expected, actual)) {
+    return AssertionSuccess();
+  }
+
+  return EqFailure(expected_expression,
+                   actual_expression,
+                   String::ShowWideCStringQuoted(expected),
+                   String::ShowWideCStringQuoted(actual),
+                   false);
+}
+
+// Helper function for *_STRNE on wide strings.
+AssertionResult CmpHelperSTRNE(const char* s1_expression,
+                               const char* s2_expression,
+                               const wchar_t* s1,
+                               const wchar_t* s2) {
+  if (!String::WideCStringEquals(s1, s2)) {
+    return AssertionSuccess();
+  }
+
+  Message msg;
+  msg << "Expected: (" << s1_expression << ") != ("
+      << s2_expression << "), actual: "
+      << String::ShowWideCStringQuoted(s1)
+      << " vs " << String::ShowWideCStringQuoted(s2);
+  return AssertionFailure(msg);
+}
+
+// Compares two C strings, ignoring case.  Returns true iff they have
+// the same content.
+//
+// Unlike strcasecmp(), this function can handle NULL argument(s).  A
+// NULL C string is considered different to any non-NULL C string,
+// including the empty string.
+bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) {
+  if (lhs == NULL)
+    return rhs == NULL;
+  if (rhs == NULL)
+    return false;
+  return posix::StrCaseCmp(lhs, rhs) == 0;
+}
+
+  // Compares two wide C strings, ignoring case.  Returns true iff they
+  // have the same content.
+  //
+  // Unlike wcscasecmp(), this function can handle NULL argument(s).
+  // A NULL C string is considered different to any non-NULL wide C string,
+  // including the empty string.
+  // NB: The implementations on different platforms slightly differ.
+  // On windows, this method uses _wcsicmp which compares according to LC_CTYPE
+  // environment variable. On GNU platform this method uses wcscasecmp
+  // which compares according to LC_CTYPE category of the current locale.
+  // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
+  // current locale.
+bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
+                                              const wchar_t* rhs) {
+  if ( lhs == NULL ) return rhs == NULL;
+
+  if ( rhs == NULL ) return false;
+
+#if GTEST_OS_WINDOWS
+  return _wcsicmp(lhs, rhs) == 0;
+#elif GTEST_OS_LINUX
+  return wcscasecmp(lhs, rhs) == 0;
+#else
+  // Mac OS X and Cygwin don't define wcscasecmp.  Other unknown OSes
+  // may not define it either.
+  wint_t left, right;
+  do {
+    left = towlower(*lhs++);
+    right = towlower(*rhs++);
+  } while (left && left == right);
+  return left == right;
+#endif  // OS selector
+}
+
+// Compares this with another String.
+// Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0
+// if this is greater than rhs.
+int String::Compare(const String & rhs) const {
+  const char* const lhs_c_str = c_str();
+  const char* const rhs_c_str = rhs.c_str();
+
+  if (lhs_c_str == NULL) {
+    return rhs_c_str == NULL ? 0 : -1;  // NULL < anything except NULL
+  } else if (rhs_c_str == NULL) {
+    return 1;
+  }
+
+  const size_t shorter_str_len =
+      length() <= rhs.length() ? length() : rhs.length();
+  for (size_t i = 0; i != shorter_str_len; i++) {
+    if (lhs_c_str[i] < rhs_c_str[i]) {
+      return -1;
+    } else if (lhs_c_str[i] > rhs_c_str[i]) {
+      return 1;
+    }
+  }
+  return (length() < rhs.length()) ? -1 :
+      (length() > rhs.length()) ? 1 : 0;
+}
+
+// Returns true iff this String ends with the given suffix.  *Any*
+// String is considered to end with a NULL or empty suffix.
+bool String::EndsWith(const char* suffix) const {
+  if (suffix == NULL || CStringEquals(suffix, "")) return true;
+
+  if (c_str() == NULL) return false;
+
+  const size_t this_len = strlen(c_str());
+  const size_t suffix_len = strlen(suffix);
+  return (this_len >= suffix_len) &&
+         CStringEquals(c_str() + this_len - suffix_len, suffix);
+}
+
+// Returns true iff this String ends with the given suffix, ignoring case.
+// Any String is considered to end with a NULL or empty suffix.
+bool String::EndsWithCaseInsensitive(const char* suffix) const {
+  if (suffix == NULL || CStringEquals(suffix, "")) return true;
+
+  if (c_str() == NULL) return false;
+
+  const size_t this_len = strlen(c_str());
+  const size_t suffix_len = strlen(suffix);
+  return (this_len >= suffix_len) &&
+         CaseInsensitiveCStringEquals(c_str() + this_len - suffix_len, suffix);
+}
+
+// Formats a list of arguments to a String, using the same format
+// spec string as for printf.
+//
+// We do not use the StringPrintf class as it is not universally
+// available.
+//
+// The result is limited to 4096 characters (including the tailing 0).
+// If 4096 characters are not enough to format the input, or if
+// there's an error, "<formatting error or buffer exceeded>" is
+// returned.
+String String::Format(const char * format, ...) {
+  va_list args;
+  va_start(args, format);
+
+  char buffer[4096];
+  const int kBufferSize = sizeof(buffer)/sizeof(buffer[0]);
+
+  // MSVC 8 deprecates vsnprintf(), so we want to suppress warning
+  // 4996 (deprecated function) there.
+#ifdef _MSC_VER  // We are using MSVC.
+#pragma warning(push)          // Saves the current warning state.
+#pragma warning(disable:4996)  // Temporarily disables warning 4996.
+  const int size = vsnprintf(buffer, kBufferSize, format, args);
+#pragma warning(pop)           // Restores the warning state.
+#else  // We are not using MSVC.
+  const int size = vsnprintf(buffer, kBufferSize, format, args);
+#endif  // _MSC_VER
+  va_end(args);
+
+  // vsnprintf()'s behavior is not portable.  When the buffer is not
+  // big enough, it returns a negative value in MSVC, and returns the
+  // needed buffer size on Linux.  When there is an output error, it
+  // always returns a negative value.  For simplicity, we lump the two
+  // error cases together.
+  if (size < 0 || size >= kBufferSize) {
+    return String("<formatting error or buffer exceeded>");
+  } else {
+    return String(buffer, size);
+  }
+}
+
+// Converts the buffer in a StrStream to a String, converting NUL
+// bytes to "\\0" along the way.
+String StrStreamToString(StrStream* ss) {
+  const ::std::string& str = ss->str();
+  const char* const start = str.c_str();
+  const char* const end = start + str.length();
+
+  // We need to use a helper StrStream to do this transformation
+  // because String doesn't support push_back().
+  StrStream helper;
+  for (const char* ch = start; ch != end; ++ch) {
+    if (*ch == '\0') {
+      helper << "\\0";  // Replaces NUL with "\\0";
+    } else {
+      helper.put(*ch);
+    }
+  }
+
+  return String(helper.str().c_str());
+}
+
+// Appends the user-supplied message to the Google-Test-generated message.
+String AppendUserMessage(const String& gtest_msg,
+                         const Message& user_msg) {
+  // Appends the user message if it's non-empty.
+  const String user_msg_string = user_msg.GetString();
+  if (user_msg_string.empty()) {
+    return gtest_msg;
+  }
+
+  Message msg;
+  msg << gtest_msg << "\n" << user_msg_string;
+
+  return msg.GetString();
+}
+
+}  // namespace internal
+
+// class TestResult
+
+// Creates an empty TestResult.
+TestResult::TestResult()
+    : death_test_count_(0),
+      elapsed_time_(0) {
+}
+
+// D'tor.
+TestResult::~TestResult() {
+}
+
+// Returns the i-th test part result among all the results. i can
+// range from 0 to total_part_count() - 1. If i is not in that range,
+// aborts the program.
+const TestPartResult& TestResult::GetTestPartResult(int i) const {
+  if (i < 0 || i >= total_part_count())
+    internal::posix::Abort();
+  return test_part_results_.at(i);
+}
+
+// Returns the i-th test property. i can range from 0 to
+// test_property_count() - 1. If i is not in that range, aborts the
+// program.
+const TestProperty& TestResult::GetTestProperty(int i) const {
+  if (i < 0 || i >= test_property_count())
+    internal::posix::Abort();
+  return test_properties_.at(i);
+}
+
+// Clears the test part results.
+void TestResult::ClearTestPartResults() {
+  test_part_results_.clear();
+}
+
+// Adds a test part result to the list.
+void TestResult::AddTestPartResult(const TestPartResult& test_part_result) {
+  test_part_results_.push_back(test_part_result);
+}
+
+// Adds a test property to the list. If a property with the same key as the
+// supplied property is already represented, the value of this test_property
+// replaces the old value for that key.
+void TestResult::RecordProperty(const TestProperty& test_property) {
+  if (!ValidateTestProperty(test_property)) {
+    return;
+  }
+  internal::MutexLock lock(&test_properites_mutex_);
+  const std::vector<TestProperty>::iterator property_with_matching_key =
+      std::find_if(test_properties_.begin(), test_properties_.end(),
+                   internal::TestPropertyKeyIs(test_property.key()));
+  if (property_with_matching_key == test_properties_.end()) {
+    test_properties_.push_back(test_property);
+    return;
+  }
+  property_with_matching_key->SetValue(test_property.value());
+}
+
+// Adds a failure if the key is a reserved attribute of Google Test
+// testcase tags.  Returns true if the property is valid.
+bool TestResult::ValidateTestProperty(const TestProperty& test_property) {
+  internal::String key(test_property.key());
+  if (key == "name" || key == "status" || key == "time" || key == "classname") {
+    ADD_FAILURE()
+        << "Reserved key used in RecordProperty(): "
+        << key
+        << " ('name', 'status', 'time', and 'classname' are reserved by "
+        << GTEST_NAME_ << ")";
+    return false;
+  }
+  return true;
+}
+
+// Clears the object.
+void TestResult::Clear() {
+  test_part_results_.clear();
+  test_properties_.clear();
+  death_test_count_ = 0;
+  elapsed_time_ = 0;
+}
+
+// Returns true iff the test failed.
+bool TestResult::Failed() const {
+  for (int i = 0; i < total_part_count(); ++i) {
+    if (GetTestPartResult(i).failed())
+      return true;
+  }
+  return false;
+}
+
+// Returns true iff the test part fatally failed.
+static bool TestPartFatallyFailed(const TestPartResult& result) {
+  return result.fatally_failed();
+}
+
+// Returns true iff the test fatally failed.
+bool TestResult::HasFatalFailure() const {
+  return CountIf(test_part_results_, TestPartFatallyFailed) > 0;
+}
+
+// Returns true iff the test part non-fatally failed.
+static bool TestPartNonfatallyFailed(const TestPartResult& result) {
+  return result.nonfatally_failed();
+}
+
+// Returns true iff the test has a non-fatal failure.
+bool TestResult::HasNonfatalFailure() const {
+  return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0;
+}
+
+// Gets the number of all test parts.  This is the sum of the number
+// of successful test parts and the number of failed test parts.
+int TestResult::total_part_count() const {
+  return static_cast<int>(test_part_results_.size());
+}
+
+// Returns the number of the test properties.
+int TestResult::test_property_count() const {
+  return static_cast<int>(test_properties_.size());
+}
+
+// class Test
+
+// Creates a Test object.
+
+// The c'tor saves the values of all Google Test flags.
+Test::Test()
+    : gtest_flag_saver_(new internal::GTestFlagSaver) {
+}
+
+// The d'tor restores the values of all Google Test flags.
+Test::~Test() {
+  delete gtest_flag_saver_;
+}
+
+// Sets up the test fixture.
+//
+// A sub-class may override this.
+void Test::SetUp() {
+}
+
+// Tears down the test fixture.
+//
+// A sub-class may override this.
+void Test::TearDown() {
+}
+
+// Allows user supplied key value pairs to be recorded for later output.
+void Test::RecordProperty(const char* key, const char* value) {
+  UnitTest::GetInstance()->RecordPropertyForCurrentTest(key, value);
+}
+
+// Allows user supplied key value pairs to be recorded for later output.
+void Test::RecordProperty(const char* key, int value) {
+  Message value_message;
+  value_message << value;
+  RecordProperty(key, value_message.GetString().c_str());
+}
+
+namespace internal {
+
+void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
+                                    const String& message) {
+  // This function is a friend of UnitTest and as such has access to
+  // AddTestPartResult.
+  UnitTest::GetInstance()->AddTestPartResult(
+      result_type,
+      NULL,  // No info about the source file where the exception occurred.
+      -1,    // We have no info on which line caused the exception.
+      message,
+      String());  // No stack trace, either.
+}
+
+}  // namespace internal
+
+#if GTEST_OS_WINDOWS
+// We are on Windows.
+
+// Adds an "exception thrown" fatal failure to the current test.
+static void AddExceptionThrownFailure(DWORD exception_code,
+                                      const char* location) {
+  Message message;
+  message << "Exception thrown with code 0x" << std::setbase(16) <<
+    exception_code << std::setbase(10) << " in " << location << ".";
+
+  internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure,
+                                           message.GetString());
+}
+
+#endif  // GTEST_OS_WINDOWS
+
+// Google Test requires all tests in the same test case to use the same test
+// fixture class.  This function checks if the current test has the
+// same fixture class as the first test in the current test case.  If
+// yes, it returns true; otherwise it generates a Google Test failure and
+// returns false.
+bool Test::HasSameFixtureClass() {
+  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+  const TestCase* const test_case = impl->current_test_case();
+
+  // Info about the first test in the current test case.
+  const internal::TestInfoImpl* const first_test_info =
+      test_case->test_info_list()[0]->impl();
+  const internal::TypeId first_fixture_id = first_test_info->fixture_class_id();
+  const char* const first_test_name = first_test_info->name();
+
+  // Info about the current test.
+  const internal::TestInfoImpl* const this_test_info =
+      impl->current_test_info()->impl();
+  const internal::TypeId this_fixture_id = this_test_info->fixture_class_id();
+  const char* const this_test_name = this_test_info->name();
+
+  if (this_fixture_id != first_fixture_id) {
+    // Is the first test defined using TEST?
+    const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId();
+    // Is this test defined using TEST?
+    const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId();
+
+    if (first_is_TEST || this_is_TEST) {
+      // The user mixed TEST and TEST_F in this test case - we'll tell
+      // him/her how to fix it.
+
+      // Gets the name of the TEST and the name of the TEST_F.  Note
+      // that first_is_TEST and this_is_TEST cannot both be true, as
+      // the fixture IDs are different for the two tests.
+      const char* const TEST_name =
+          first_is_TEST ? first_test_name : this_test_name;
+      const char* const TEST_F_name =
+          first_is_TEST ? this_test_name : first_test_name;
+
+      ADD_FAILURE()
+          << "All tests in the same test case must use the same test fixture\n"
+          << "class, so mixing TEST_F and TEST in the same test case is\n"
+          << "illegal.  In test case " << this_test_info->test_case_name()
+          << ",\n"
+          << "test " << TEST_F_name << " is defined using TEST_F but\n"
+          << "test " << TEST_name << " is defined using TEST.  You probably\n"
+          << "want to change the TEST to TEST_F or move it to another test\n"
+          << "case.";
+    } else {
+      // The user defined two fixture classes with the same name in
+      // two namespaces - we'll tell him/her how to fix it.
+      ADD_FAILURE()
+          << "All tests in the same test case must use the same test fixture\n"
+          << "class.  However, in test case "
+          << this_test_info->test_case_name() << ",\n"
+          << "you defined test " << first_test_name
+          << " and test " << this_test_name << "\n"
+          << "using two different test fixture classes.  This can happen if\n"
+          << "the two classes are from different namespaces or translation\n"
+          << "units and have the same name.  You should probably rename one\n"
+          << "of the classes to put the tests into different test cases.";
+    }
+    return false;
+  }
+
+  return true;
+}
+
+// Runs the test and updates the test result.
+void Test::Run() {
+  if (!HasSameFixtureClass()) return;
+
+  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+#if GTEST_HAS_SEH
+  // Catch SEH-style exceptions.
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  __try {
+    SetUp();
+  } __except(internal::UnitTestOptions::GTestShouldProcessSEH(
+      GetExceptionCode())) {
+    AddExceptionThrownFailure(GetExceptionCode(), "SetUp()");
+  }
+
+  // We will run the test only if SetUp() had no fatal failure.
+  if (!HasFatalFailure()) {
+    impl->os_stack_trace_getter()->UponLeavingGTest();
+    __try {
+      TestBody();
+    } __except(internal::UnitTestOptions::GTestShouldProcessSEH(
+        GetExceptionCode())) {
+      AddExceptionThrownFailure(GetExceptionCode(), "the test body");
+    }
+  }
+
+  // However, we want to clean up as much as possible.  Hence we will
+  // always call TearDown(), even if SetUp() or the test body has
+  // failed.
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  __try {
+    TearDown();
+  } __except(internal::UnitTestOptions::GTestShouldProcessSEH(
+      GetExceptionCode())) {
+    AddExceptionThrownFailure(GetExceptionCode(), "TearDown()");
+  }
+
+#else  // We are on a compiler or platform that doesn't support SEH.
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  SetUp();
+
+  // We will run the test only if SetUp() was successful.
+  if (!HasFatalFailure()) {
+    impl->os_stack_trace_getter()->UponLeavingGTest();
+    TestBody();
+  }
+
+  // However, we want to clean up as much as possible.  Hence we will
+  // always call TearDown(), even if SetUp() or the test body has
+  // failed.
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  TearDown();
+#endif  // GTEST_HAS_SEH
+}
+
+
+// Returns true iff the current test has a fatal failure.
+bool Test::HasFatalFailure() {
+  return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure();
+}
+
+// Returns true iff the current test has a non-fatal failure.
+bool Test::HasNonfatalFailure() {
+  return internal::GetUnitTestImpl()->current_test_result()->
+      HasNonfatalFailure();
+}
+
+// class TestInfo
+
+// Constructs a TestInfo object. It assumes ownership of the test factory
+// object via impl_.
+TestInfo::TestInfo(const char* a_test_case_name,
+                   const char* a_name,
+                   const char* a_test_case_comment,
+                   const char* a_comment,
+                   internal::TypeId fixture_class_id,
+                   internal::TestFactoryBase* factory) {
+  impl_ = new internal::TestInfoImpl(this, a_test_case_name, a_name,
+                                     a_test_case_comment, a_comment,
+                                     fixture_class_id, factory);
+}
+
+// Destructs a TestInfo object.
+TestInfo::~TestInfo() {
+  delete impl_;
+}
+
+namespace internal {
+
+// Creates a new TestInfo object and registers it with Google Test;
+// returns the created object.
+//
+// Arguments:
+//
+//   test_case_name:   name of the test case
+//   name:             name of the test
+//   test_case_comment: a comment on the test case that will be included in
+//                      the test output
+//   comment:          a comment on the test that will be included in the
+//                     test output
+//   fixture_class_id: ID of the test fixture class
+//   set_up_tc:        pointer to the function that sets up the test case
+//   tear_down_tc:     pointer to the function that tears down the test case
+//   factory:          pointer to the factory that creates a test object.
+//                     The newly created TestInfo instance will assume
+//                     ownership of the factory object.
+TestInfo* MakeAndRegisterTestInfo(
+    const char* test_case_name, const char* name,
+    const char* test_case_comment, const char* comment,
+    TypeId fixture_class_id,
+    SetUpTestCaseFunc set_up_tc,
+    TearDownTestCaseFunc tear_down_tc,
+    TestFactoryBase* factory) {
+  TestInfo* const test_info =
+      new TestInfo(test_case_name, name, test_case_comment, comment,
+                   fixture_class_id, factory);
+  GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
+  return test_info;
+}
+
+#if GTEST_HAS_PARAM_TEST
+void ReportInvalidTestCaseType(const char* test_case_name,
+                               const char* file, int line) {
+  Message errors;
+  errors
+      << "Attempted redefinition of test case " << test_case_name << ".\n"
+      << "All tests in the same test case must use the same test fixture\n"
+      << "class.  However, in test case " << test_case_name << ", you tried\n"
+      << "to define a test using a fixture class different from the one\n"
+      << "used earlier. This can happen if the two fixture classes are\n"
+      << "from different namespaces and have the same name. You should\n"
+      << "probably rename one of the classes to put the tests into different\n"
+      << "test cases.";
+
+  fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
+          errors.GetString().c_str());
+}
+#endif  // GTEST_HAS_PARAM_TEST
+
+}  // namespace internal
+
+// Returns the test case name.
+const char* TestInfo::test_case_name() const {
+  return impl_->test_case_name();
+}
+
+// Returns the test name.
+const char* TestInfo::name() const {
+  return impl_->name();
+}
+
+// Returns the test case comment.
+const char* TestInfo::test_case_comment() const {
+  return impl_->test_case_comment();
+}
+
+// Returns the test comment.
+const char* TestInfo::comment() const {
+  return impl_->comment();
+}
+
+// Returns true if this test should run.
+bool TestInfo::should_run() const { return impl_->should_run(); }
+
+// Returns true if this test matches the user-specified filter.
+bool TestInfo::matches_filter() const { return impl_->matches_filter(); }
+
+// Returns the result of the test.
+const TestResult* TestInfo::result() const { return impl_->result(); }
+
+// Increments the number of death tests encountered in this test so
+// far.
+int TestInfo::increment_death_test_count() {
+  return impl_->result()->increment_death_test_count();
+}
+
+namespace {
+
+// A predicate that checks the test name of a TestInfo against a known
+// value.
+//
+// This is used for implementation of the TestCase class only.  We put
+// it in the anonymous namespace to prevent polluting the outer
+// namespace.
+//
+// TestNameIs is copyable.
+class TestNameIs {
+ public:
+  // Constructor.
+  //
+  // TestNameIs has NO default constructor.
+  explicit TestNameIs(const char* name)
+      : name_(name) {}
+
+  // Returns true iff the test name of test_info matches name_.
+  bool operator()(const TestInfo * test_info) const {
+    return test_info && internal::String(test_info->name()).Compare(name_) == 0;
+  }
+
+ private:
+  internal::String name_;
+};
+
+}  // namespace
+
+namespace internal {
+
+// This method expands all parameterized tests registered with macros TEST_P
+// and INSTANTIATE_TEST_CASE_P into regular tests and registers those.
+// This will be done just once during the program runtime.
+void UnitTestImpl::RegisterParameterizedTests() {
+#if GTEST_HAS_PARAM_TEST
+  if (!parameterized_tests_registered_) {
+    parameterized_test_registry_.RegisterTests();
+    parameterized_tests_registered_ = true;
+  }
+#endif
+}
+
+// Creates the test object, runs it, records its result, and then
+// deletes it.
+void TestInfoImpl::Run() {
+  if (!should_run_) return;
+
+  // Tells UnitTest where to store test result.
+  UnitTestImpl* const impl = internal::GetUnitTestImpl();
+  impl->set_current_test_info(parent_);
+
+  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
+
+  // Notifies the unit test event listeners that a test is about to start.
+  repeater->OnTestStart(*parent_);
+
+  const TimeInMillis start = GetTimeInMillis();
+
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+#if GTEST_HAS_SEH
+  // Catch SEH-style exceptions.
+  Test* test = NULL;
+
+  __try {
+    // Creates the test object.
+    test = factory_->CreateTest();
+  } __except(internal::UnitTestOptions::GTestShouldProcessSEH(
+      GetExceptionCode())) {
+    AddExceptionThrownFailure(GetExceptionCode(),
+                              "the test fixture's constructor");
+    return;
+  }
+#else  // We are on a compiler or platform that doesn't support SEH.
+
+  // TODO(wan): If test->Run() throws, test won't be deleted.  This is
+  // not a problem now as we don't use exceptions.  If we were to
+  // enable exceptions, we should revise the following to be
+  // exception-safe.
+
+  // Creates the test object.
+  Test* test = factory_->CreateTest();
+#endif  // GTEST_HAS_SEH
+
+  // Runs the test only if the constructor of the test fixture didn't
+  // generate a fatal failure.
+  if (!Test::HasFatalFailure()) {
+    test->Run();
+  }
+
+  // Deletes the test object.
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  delete test;
+  test = NULL;
+
+  result_.set_elapsed_time(GetTimeInMillis() - start);
+
+  // Notifies the unit test event listener that a test has just finished.
+  repeater->OnTestEnd(*parent_);
+
+  // Tells UnitTest to stop associating assertion results to this
+  // test.
+  impl->set_current_test_info(NULL);
+}
+
+}  // namespace internal
+
+// class TestCase
+
+// Gets the number of successful tests in this test case.
+int TestCase::successful_test_count() const {
+  return CountIf(test_info_list_, TestPassed);
+}
+
+// Gets the number of failed tests in this test case.
+int TestCase::failed_test_count() const {
+  return CountIf(test_info_list_, TestFailed);
+}
+
+int TestCase::disabled_test_count() const {
+  return CountIf(test_info_list_, TestDisabled);
+}
+
+// Get the number of tests in this test case that should run.
+int TestCase::test_to_run_count() const {
+  return CountIf(test_info_list_, ShouldRunTest);
+}
+
+// Gets the number of all tests.
+int TestCase::total_test_count() const {
+  return static_cast<int>(test_info_list_.size());
+}
+
+// Creates a TestCase with the given name.
+//
+// Arguments:
+//
+//   name:         name of the test case
+//   set_up_tc:    pointer to the function that sets up the test case
+//   tear_down_tc: pointer to the function that tears down the test case
+TestCase::TestCase(const char* a_name, const char* a_comment,
+                   Test::SetUpTestCaseFunc set_up_tc,
+                   Test::TearDownTestCaseFunc tear_down_tc)
+    : name_(a_name),
+      comment_(a_comment),
+      set_up_tc_(set_up_tc),
+      tear_down_tc_(tear_down_tc),
+      should_run_(false),
+      elapsed_time_(0) {
+}
+
+// Destructor of TestCase.
+TestCase::~TestCase() {
+  // Deletes every Test in the collection.
+  ForEach(test_info_list_, internal::Delete<TestInfo>);
+}
+
+// Returns the i-th test among all the tests. i can range from 0 to
+// total_test_count() - 1. If i is not in that range, returns NULL.
+const TestInfo* TestCase::GetTestInfo(int i) const {
+  const int index = GetElementOr(test_indices_, i, -1);
+  return index < 0 ? NULL : test_info_list_[index];
+}
+
+// Returns the i-th test among all the tests. i can range from 0 to
+// total_test_count() - 1. If i is not in that range, returns NULL.
+TestInfo* TestCase::GetMutableTestInfo(int i) {
+  const int index = GetElementOr(test_indices_, i, -1);
+  return index < 0 ? NULL : test_info_list_[index];
+}
+
+// Adds a test to this test case.  Will delete the test upon
+// destruction of the TestCase object.
+void TestCase::AddTestInfo(TestInfo * test_info) {
+  test_info_list_.push_back(test_info);
+  test_indices_.push_back(static_cast<int>(test_indices_.size()));
+}
+
+// Runs every test in this TestCase.
+void TestCase::Run() {
+  if (!should_run_) return;
+
+  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+  impl->set_current_test_case(this);
+
+  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
+
+  repeater->OnTestCaseStart(*this);
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  set_up_tc_();
+
+  const internal::TimeInMillis start = internal::GetTimeInMillis();
+  for (int i = 0; i < total_test_count(); i++) {
+    GetMutableTestInfo(i)->impl()->Run();
+  }
+  elapsed_time_ = internal::GetTimeInMillis() - start;
+
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  tear_down_tc_();
+  repeater->OnTestCaseEnd(*this);
+  impl->set_current_test_case(NULL);
+}
+
+// Clears the results of all tests in this test case.
+void TestCase::ClearResult() {
+  ForEach(test_info_list_, internal::TestInfoImpl::ClearTestResult);
+}
+
+// Returns true iff test passed.
+bool TestCase::TestPassed(const TestInfo * test_info) {
+  const internal::TestInfoImpl* const impl = test_info->impl();
+  return impl->should_run() && impl->result()->Passed();
+}
+
+// Returns true iff test failed.
+bool TestCase::TestFailed(const TestInfo * test_info) {
+  const internal::TestInfoImpl* const impl = test_info->impl();
+  return impl->should_run() && impl->result()->Failed();
+}
+
+// Returns true iff test is disabled.
+bool TestCase::TestDisabled(const TestInfo * test_info) {
+  return test_info->impl()->is_disabled();
+}
+
+// Returns true if the given test should run.
+bool TestCase::ShouldRunTest(const TestInfo *test_info) {
+  return test_info->impl()->should_run();
+}
+
+// Shuffles the tests in this test case.
+void TestCase::ShuffleTests(internal::Random* random) {
+  Shuffle(random, &test_indices_);
+}
+
+// Restores the test order to before the first shuffle.
+void TestCase::UnshuffleTests() {
+  for (size_t i = 0; i < test_indices_.size(); i++) {
+    test_indices_[i] = static_cast<int>(i);
+  }
+}
+
+// Formats a countable noun.  Depending on its quantity, either the
+// singular form or the plural form is used. e.g.
+//
+// FormatCountableNoun(1, "formula", "formuli") returns "1 formula".
+// FormatCountableNoun(5, "book", "books") returns "5 books".
+static internal::String FormatCountableNoun(int count,
+                                            const char * singular_form,
+                                            const char * plural_form) {
+  return internal::String::Format("%d %s", count,
+                                  count == 1 ? singular_form : plural_form);
+}
+
+// Formats the count of tests.
+static internal::String FormatTestCount(int test_count) {
+  return FormatCountableNoun(test_count, "test", "tests");
+}
+
+// Formats the count of test cases.
+static internal::String FormatTestCaseCount(int test_case_count) {
+  return FormatCountableNoun(test_case_count, "test case", "test cases");
+}
+
+// Converts a TestPartResult::Type enum to human-friendly string
+// representation.  Both kNonFatalFailure and kFatalFailure are translated
+// to "Failure", as the user usually doesn't care about the difference
+// between the two when viewing the test result.
+static const char * TestPartResultTypeToString(TestPartResult::Type type) {
+  switch (type) {
+    case TestPartResult::kSuccess:
+      return "Success";
+
+    case TestPartResult::kNonFatalFailure:
+    case TestPartResult::kFatalFailure:
+#ifdef _MSC_VER
+      return "error: ";
+#else
+      return "Failure\n";
+#endif
+  }
+
+  return "Unknown result type";
+}
+
+// Prints a TestPartResult to a String.
+static internal::String PrintTestPartResultToString(
+    const TestPartResult& test_part_result) {
+  return (Message()
+          << internal::FormatFileLocation(test_part_result.file_name(),
+                                          test_part_result.line_number())
+          << " " << TestPartResultTypeToString(test_part_result.type())
+          << test_part_result.message()).GetString();
+}
+
+// Prints a TestPartResult.
+static void PrintTestPartResult(const TestPartResult& test_part_result) {
+  const internal::String& result =
+      PrintTestPartResultToString(test_part_result);
+  printf("%s\n", result.c_str());
+  fflush(stdout);
+  // If the test program runs in Visual Studio or a debugger, the
+  // following statements add the test part result message to the Output
+  // window such that the user can double-click on it to jump to the
+  // corresponding source code location; otherwise they do nothing.
+#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+  // We don't call OutputDebugString*() on Windows Mobile, as printing
+  // to stdout is done by OutputDebugString() there already - we don't
+  // want the same message printed twice.
+  ::OutputDebugStringA(result.c_str());
+  ::OutputDebugStringA("\n");
+#endif
+}
+
+// class PrettyUnitTestResultPrinter
+
+namespace internal {
+
+enum GTestColor {
+  COLOR_DEFAULT,
+  COLOR_RED,
+  COLOR_GREEN,
+  COLOR_YELLOW
+};
+
+#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+
+// Returns the character attribute for the given color.
+WORD GetColorAttribute(GTestColor color) {
+  switch (color) {
+    case COLOR_RED:    return FOREGROUND_RED;
+    case COLOR_GREEN:  return FOREGROUND_GREEN;
+    case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN;
+    default:           return 0;
+  }
+}
+
+#else
+
+// Returns the ANSI color code for the given color.  COLOR_DEFAULT is
+// an invalid input.
+const char* GetAnsiColorCode(GTestColor color) {
+  switch (color) {
+    case COLOR_RED:     return "1";
+    case COLOR_GREEN:   return "2";
+    case COLOR_YELLOW:  return "3";
+    default:            return NULL;
+  };
+}
+
+#endif  // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+
+// Returns true iff Google Test should use colors in the output.
+bool ShouldUseColor(bool stdout_is_tty) {
+  const char* const gtest_color = GTEST_FLAG(color).c_str();
+
+  if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) {
+#if GTEST_OS_WINDOWS
+    // On Windows the TERM variable is usually not set, but the
+    // console there does support colors.
+    return stdout_is_tty;
+#else
+    // On non-Windows platforms, we rely on the TERM variable.
+    const char* const term = posix::GetEnv("TERM");
+    const bool term_supports_color =
+        String::CStringEquals(term, "xterm") ||
+        String::CStringEquals(term, "xterm-color") ||
+        String::CStringEquals(term, "xterm-256color") ||
+        String::CStringEquals(term, "linux") ||
+        String::CStringEquals(term, "cygwin");
+    return stdout_is_tty && term_supports_color;
+#endif  // GTEST_OS_WINDOWS
+  }
+
+  return String::CaseInsensitiveCStringEquals(gtest_color, "yes") ||
+      String::CaseInsensitiveCStringEquals(gtest_color, "true") ||
+      String::CaseInsensitiveCStringEquals(gtest_color, "t") ||
+      String::CStringEquals(gtest_color, "1");
+  // We take "yes", "true", "t", and "1" as meaning "yes".  If the
+  // value is neither one of these nor "auto", we treat it as "no" to
+  // be conservative.
+}
+
+// Helpers for printing colored strings to stdout. Note that on Windows, we
+// cannot simply emit special characters and have the terminal change colors.
+// This routine must actually emit the characters rather than return a string
+// that would be colored when printed, as can be done on Linux.
+void ColoredPrintf(GTestColor color, const char* fmt, ...) {
+  va_list args;
+  va_start(args, fmt);
+
+#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS
+  const bool use_color = false;
+#else
+  static const bool in_color_mode =
+      ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0);
+  const bool use_color = in_color_mode && (color != COLOR_DEFAULT);
+#endif  // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS
+  // The '!= 0' comparison is necessary to satisfy MSVC 7.1.
+
+  if (!use_color) {
+    vprintf(fmt, args);
+    va_end(args);
+    return;
+  }
+
+#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+  const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
+
+  // Gets the current text color.
+  CONSOLE_SCREEN_BUFFER_INFO buffer_info;
+  GetConsoleScreenBufferInfo(stdout_handle, &buffer_info);
+  const WORD old_color_attrs = buffer_info.wAttributes;
+
+  // We need to flush the stream buffers into the console before each
+  // SetConsoleTextAttribute call lest it affect the text that is already
+  // printed but has not yet reached the console.
+  fflush(stdout);
+  SetConsoleTextAttribute(stdout_handle,
+                          GetColorAttribute(color) | FOREGROUND_INTENSITY);
+  vprintf(fmt, args);
+
+  fflush(stdout);
+  // Restores the text color.
+  SetConsoleTextAttribute(stdout_handle, old_color_attrs);
+#else
+  printf("\033[0;3%sm", GetAnsiColorCode(color));
+  vprintf(fmt, args);
+  printf("\033[m");  // Resets the terminal to default.
+#endif  // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+  va_end(args);
+}
+
+// This class implements the TestEventListener interface.
+//
+// Class PrettyUnitTestResultPrinter is copyable.
+class PrettyUnitTestResultPrinter : public TestEventListener {
+ public:
+  PrettyUnitTestResultPrinter() {}
+  static void PrintTestName(const char * test_case, const char * test) {
+    printf("%s.%s", test_case, test);
+  }
+
+  // The following methods override what's in the TestEventListener class.
+  virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);
+  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);
+  virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestCaseStart(const TestCase& test_case);
+  virtual void OnTestStart(const TestInfo& test_info);
+  virtual void OnTestPartResult(const TestPartResult& result);
+  virtual void OnTestEnd(const TestInfo& test_info);
+  virtual void OnTestCaseEnd(const TestCase& test_case);
+  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);
+  virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
+  virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}
+
+ private:
+  static void PrintFailedTests(const UnitTest& unit_test);
+
+  internal::String test_case_name_;
+};
+
+  // Fired before each iteration of tests starts.
+void PrettyUnitTestResultPrinter::OnTestIterationStart(
+    const UnitTest& unit_test, int iteration) {
+  if (GTEST_FLAG(repeat) != 1)
+    printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1);
+
+  const char* const filter = GTEST_FLAG(filter).c_str();
+
+  // Prints the filter if it's not *.  This reminds the user that some
+  // tests may be skipped.
+  if (!internal::String::CStringEquals(filter, kUniversalFilter)) {
+    ColoredPrintf(COLOR_YELLOW,
+                  "Note: %s filter = %s\n", GTEST_NAME_, filter);
+  }
+
+  if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) {
+    ColoredPrintf(COLOR_YELLOW,
+                  "Note: This is test shard %s of %s.\n",
+                  internal::posix::GetEnv(kTestShardIndex),
+                  internal::posix::GetEnv(kTestTotalShards));
+  }
+
+  if (GTEST_FLAG(shuffle)) {
+    ColoredPrintf(COLOR_YELLOW,
+                  "Note: Randomizing tests' orders with a seed of %d .\n",
+                  unit_test.random_seed());
+  }
+
+  ColoredPrintf(COLOR_GREEN,  "[==========] ");
+  printf("Running %s from %s.\n",
+         FormatTestCount(unit_test.test_to_run_count()).c_str(),
+         FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str());
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart(
+    const UnitTest& /*unit_test*/) {
+  ColoredPrintf(COLOR_GREEN,  "[----------] ");
+  printf("Global test environment set-up.\n");
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {
+  test_case_name_ = test_case.name();
+  const internal::String counts =
+      FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
+  ColoredPrintf(COLOR_GREEN, "[----------] ");
+  printf("%s from %s", counts.c_str(), test_case_name_.c_str());
+  if (test_case.comment()[0] == '\0') {
+    printf("\n");
+  } else {
+    printf(", where %s\n", test_case.comment());
+  }
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {
+  ColoredPrintf(COLOR_GREEN,  "[ RUN      ] ");
+  PrintTestName(test_case_name_.c_str(), test_info.name());
+  if (test_info.comment()[0] == '\0') {
+    printf("\n");
+  } else {
+    printf(", where %s\n", test_info.comment());
+  }
+  fflush(stdout);
+}
+
+// Called after an assertion failure.
+void PrettyUnitTestResultPrinter::OnTestPartResult(
+    const TestPartResult& result) {
+  // If the test part succeeded, we don't need to do anything.
+  if (result.type() == TestPartResult::kSuccess)
+    return;
+
+  // Print failure message from the assertion (e.g. expected this and got that).
+  PrintTestPartResult(result);
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {
+  if (test_info.result()->Passed()) {
+    ColoredPrintf(COLOR_GREEN, "[       OK ] ");
+  } else {
+    ColoredPrintf(COLOR_RED, "[  FAILED  ] ");
+  }
+  PrintTestName(test_case_name_.c_str(), test_info.name());
+  if (GTEST_FLAG(print_time)) {
+    printf(" (%s ms)\n", internal::StreamableToString(
+           test_info.result()->elapsed_time()).c_str());
+  } else {
+    printf("\n");
+  }
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {
+  if (!GTEST_FLAG(print_time)) return;
+
+  test_case_name_ = test_case.name();
+  const internal::String counts =
+      FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
+  ColoredPrintf(COLOR_GREEN, "[----------] ");
+  printf("%s from %s (%s ms total)\n\n",
+         counts.c_str(), test_case_name_.c_str(),
+         internal::StreamableToString(test_case.elapsed_time()).c_str());
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart(
+    const UnitTest& /*unit_test*/) {
+  ColoredPrintf(COLOR_GREEN,  "[----------] ");
+  printf("Global test environment tear-down\n");
+  fflush(stdout);
+}
+
+// Internal helper for printing the list of failed tests.
+void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) {
+  const int failed_test_count = unit_test.failed_test_count();
+  if (failed_test_count == 0) {
+    return;
+  }
+
+  for (int i = 0; i < unit_test.total_test_case_count(); ++i) {
+    const TestCase& test_case = *unit_test.GetTestCase(i);
+    if (!test_case.should_run() || (test_case.failed_test_count() == 0)) {
+      continue;
+    }
+    for (int j = 0; j < test_case.total_test_count(); ++j) {
+      const TestInfo& test_info = *test_case.GetTestInfo(j);
+      if (!test_info.should_run() || test_info.result()->Passed()) {
+        continue;
+      }
+      ColoredPrintf(COLOR_RED, "[  FAILED  ] ");
+      printf("%s.%s", test_case.name(), test_info.name());
+      if (test_case.comment()[0] != '\0' ||
+          test_info.comment()[0] != '\0') {
+        printf(", where %s", test_case.comment());
+        if (test_case.comment()[0] != '\0' &&
+            test_info.comment()[0] != '\0') {
+          printf(" and ");
+        }
+      }
+      printf("%s\n", test_info.comment());
+    }
+  }
+}
+
+ void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
+                                                      int /*iteration*/) {
+  ColoredPrintf(COLOR_GREEN,  "[==========] ");
+  printf("%s from %s ran.",
+         FormatTestCount(unit_test.test_to_run_count()).c_str(),
+         FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str());
+  if (GTEST_FLAG(print_time)) {
+    printf(" (%s ms total)",
+           internal::StreamableToString(unit_test.elapsed_time()).c_str());
+  }
+  printf("\n");
+  ColoredPrintf(COLOR_GREEN,  "[  PASSED  ] ");
+  printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str());
+
+  int num_failures = unit_test.failed_test_count();
+  if (!unit_test.Passed()) {
+    const int failed_test_count = unit_test.failed_test_count();
+    ColoredPrintf(COLOR_RED,  "[  FAILED  ] ");
+    printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str());
+    PrintFailedTests(unit_test);
+    printf("\n%2d FAILED %s\n", num_failures,
+                        num_failures == 1 ? "TEST" : "TESTS");
+  }
+
+  int num_disabled = unit_test.disabled_test_count();
+  if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) {
+    if (!num_failures) {
+      printf("\n");  // Add a spacer if no FAILURE banner is displayed.
+    }
+    ColoredPrintf(COLOR_YELLOW,
+                  "  YOU HAVE %d DISABLED %s\n\n",
+                  num_disabled,
+                  num_disabled == 1 ? "TEST" : "TESTS");
+  }
+  // Ensure that Google Test output is printed before, e.g., heapchecker output.
+  fflush(stdout);
+}
+
+// End PrettyUnitTestResultPrinter
+
+// class TestEventRepeater
+//
+// This class forwards events to other event listeners.
+class TestEventRepeater : public TestEventListener {
+ public:
+  TestEventRepeater() : forwarding_enabled_(true) {}
+  virtual ~TestEventRepeater();
+  void Append(TestEventListener *listener);
+  TestEventListener* Release(TestEventListener* listener);
+
+  // Controls whether events will be forwarded to listeners_. Set to false
+  // in death test child processes.
+  bool forwarding_enabled() const { return forwarding_enabled_; }
+  void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; }
+
+  virtual void OnTestProgramStart(const UnitTest& unit_test);
+  virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);
+  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);
+  virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test);
+  virtual void OnTestCaseStart(const TestCase& test_case);
+  virtual void OnTestStart(const TestInfo& test_info);
+  virtual void OnTestPartResult(const TestPartResult& result);
+  virtual void OnTestEnd(const TestInfo& test_info);
+  virtual void OnTestCaseEnd(const TestCase& test_case);
+  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);
+  virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test);
+  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
+  virtual void OnTestProgramEnd(const UnitTest& unit_test);
+
+ private:
+  // Controls whether events will be forwarded to listeners_. Set to false
+  // in death test child processes.
+  bool forwarding_enabled_;
+  // The list of listeners that receive events.
+  std::vector<TestEventListener*> listeners_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater);
+};
+
+TestEventRepeater::~TestEventRepeater() {
+  ForEach(listeners_, Delete<TestEventListener>);
+}
+
+void TestEventRepeater::Append(TestEventListener *listener) {
+  listeners_.push_back(listener);
+}
+
+// TODO(vladl@google.com): Factor the search functionality into Vector::Find.
+TestEventListener* TestEventRepeater::Release(TestEventListener *listener) {
+  for (size_t i = 0; i < listeners_.size(); ++i) {
+    if (listeners_[i] == listener) {
+      listeners_.erase(listeners_.begin() + i);
+      return listener;
+    }
+  }
+
+  return NULL;
+}
+
+// Since most methods are very similar, use macros to reduce boilerplate.
+// This defines a member that forwards the call to all listeners.
+#define GTEST_REPEATER_METHOD_(Name, Type) \
+void TestEventRepeater::Name(const Type& parameter) { \
+  if (forwarding_enabled_) { \
+    for (size_t i = 0; i < listeners_.size(); i++) { \
+      listeners_[i]->Name(parameter); \
+    } \
+  } \
+}
+// This defines a member that forwards the call to all listeners in reverse
+// order.
+#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \
+void TestEventRepeater::Name(const Type& parameter) { \
+  if (forwarding_enabled_) { \
+    for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) { \
+      listeners_[i]->Name(parameter); \
+    } \
+  } \
+}
+
+GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest)
+GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest)
+GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase)
+GTEST_REPEATER_METHOD_(OnTestStart, TestInfo)
+GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult)
+GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest)
+GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest)
+GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest)
+GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo)
+GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase)
+GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest)
+
+#undef GTEST_REPEATER_METHOD_
+#undef GTEST_REVERSE_REPEATER_METHOD_
+
+void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test,
+                                             int iteration) {
+  if (forwarding_enabled_) {
+    for (size_t i = 0; i < listeners_.size(); i++) {
+      listeners_[i]->OnTestIterationStart(unit_test, iteration);
+    }
+  }
+}
+
+void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test,
+                                           int iteration) {
+  if (forwarding_enabled_) {
+    for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) {
+      listeners_[i]->OnTestIterationEnd(unit_test, iteration);
+    }
+  }
+}
+
+// End TestEventRepeater
+
+// This class generates an XML output file.
+class XmlUnitTestResultPrinter : public EmptyTestEventListener {
+ public:
+  explicit XmlUnitTestResultPrinter(const char* output_file);
+
+  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
+
+ private:
+  // Is c a whitespace character that is normalized to a space character
+  // when it appears in an XML attribute value?
+  static bool IsNormalizableWhitespace(char c) {
+    return c == 0x9 || c == 0xA || c == 0xD;
+  }
+
+  // May c appear in a well-formed XML document?
+  static bool IsValidXmlCharacter(char c) {
+    return IsNormalizableWhitespace(c) || c >= 0x20;
+  }
+
+  // Returns an XML-escaped copy of the input string str.  If
+  // is_attribute is true, the text is meant to appear as an attribute
+  // value, and normalizable whitespace is preserved by replacing it
+  // with character references.
+  static String EscapeXml(const char* str, bool is_attribute);
+
+  // Returns the given string with all characters invalid in XML removed.
+  static String RemoveInvalidXmlCharacters(const char* str);
+
+  // Convenience wrapper around EscapeXml when str is an attribute value.
+  static String EscapeXmlAttribute(const char* str) {
+    return EscapeXml(str, true);
+  }
+
+  // Convenience wrapper around EscapeXml when str is not an attribute value.
+  static String EscapeXmlText(const char* str) { return EscapeXml(str, false); }
+
+  // Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
+  static void OutputXmlCDataSection(::std::ostream* stream, const char* data);
+
+  // Streams an XML representation of a TestInfo object.
+  static void OutputXmlTestInfo(::std::ostream* stream,
+                                const char* test_case_name,
+                                const TestInfo& test_info);
+
+  // Prints an XML representation of a TestCase object
+  static void PrintXmlTestCase(FILE* out, const TestCase& test_case);
+
+  // Prints an XML summary of unit_test to output stream out.
+  static void PrintXmlUnitTest(FILE* out, const UnitTest& unit_test);
+
+  // Produces a string representing the test properties in a result as space
+  // delimited XML attributes based on the property key="value" pairs.
+  // When the String is not empty, it includes a space at the beginning,
+  // to delimit this attribute from prior attributes.
+  static String TestPropertiesAsXmlAttributes(const TestResult& result);
+
+  // The output file.
+  const String output_file_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter);
+};
+
+// Creates a new XmlUnitTestResultPrinter.
+XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)
+    : output_file_(output_file) {
+  if (output_file_.c_str() == NULL || output_file_.empty()) {
+    fprintf(stderr, "XML output file may not be null\n");
+    fflush(stderr);
+    exit(EXIT_FAILURE);
+  }
+}
+
+// Called after the unit test ends.
+void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
+                                                  int /*iteration*/) {
+  FILE* xmlout = NULL;
+  FilePath output_file(output_file_);
+  FilePath output_dir(output_file.RemoveFileName());
+
+  if (output_dir.CreateDirectoriesRecursively()) {
+    xmlout = posix::FOpen(output_file_.c_str(), "w");
+  }
+  if (xmlout == NULL) {
+    // TODO(wan): report the reason of the failure.
+    //
+    // We don't do it for now as:
+    //
+    //   1. There is no urgent need for it.
+    //   2. It's a bit involved to make the errno variable thread-safe on
+    //      all three operating systems (Linux, Windows, and Mac OS).
+    //   3. To interpret the meaning of errno in a thread-safe way,
+    //      we need the strerror_r() function, which is not available on
+    //      Windows.
+    fprintf(stderr,
+            "Unable to open file \"%s\"\n",
+            output_file_.c_str());
+    fflush(stderr);
+    exit(EXIT_FAILURE);
+  }
+  PrintXmlUnitTest(xmlout, unit_test);
+  fclose(xmlout);
+}
+
+// Returns an XML-escaped copy of the input string str.  If is_attribute
+// is true, the text is meant to appear as an attribute value, and
+// normalizable whitespace is preserved by replacing it with character
+// references.
+//
+// Invalid XML characters in str, if any, are stripped from the output.
+// It is expected that most, if not all, of the text processed by this
+// module will consist of ordinary English text.
+// If this module is ever modified to produce version 1.1 XML output,
+// most invalid characters can be retained using character references.
+// TODO(wan): It might be nice to have a minimally invasive, human-readable
+// escaping scheme for invalid characters, rather than dropping them.
+String XmlUnitTestResultPrinter::EscapeXml(const char* str, bool is_attribute) {
+  Message m;
+
+  if (str != NULL) {
+    for (const char* src = str; *src; ++src) {
+      switch (*src) {
+        case '<':
+          m << "&lt;";
+          break;
+        case '>':
+          m << "&gt;";
+          break;
+        case '&':
+          m << "&amp;";
+          break;
+        case '\'':
+          if (is_attribute)
+            m << "&apos;";
+          else
+            m << '\'';
+          break;
+        case '"':
+          if (is_attribute)
+            m << "&quot;";
+          else
+            m << '"';
+          break;
+        default:
+          if (IsValidXmlCharacter(*src)) {
+            if (is_attribute && IsNormalizableWhitespace(*src))
+              m << String::Format("&#x%02X;", unsigned(*src));
+            else
+              m << *src;
+          }
+          break;
+      }
+    }
+  }
+
+  return m.GetString();
+}
+
+// Returns the given string with all characters invalid in XML removed.
+// Currently invalid characters are dropped from the string. An
+// alternative is to replace them with certain characters such as . or ?.
+String XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(const char* str) {
+  char* const output = new char[strlen(str) + 1];
+  char* appender = output;
+  for (char ch = *str; ch != '\0'; ch = *++str)
+    if (IsValidXmlCharacter(ch))
+      *appender++ = ch;
+  *appender = '\0';
+
+  String ret_value(output);
+  delete[] output;
+  return ret_value;
+}
+
+// The following routines generate an XML representation of a UnitTest
+// object.
+//
+// This is how Google Test concepts map to the DTD:
+//
+// <testsuites name="AllTests">        <-- corresponds to a UnitTest object
+//   <testsuite name="testcase-name">  <-- corresponds to a TestCase object
+//     <testcase name="test-name">     <-- corresponds to a TestInfo object
+//       <failure message="...">...</failure>
+//       <failure message="...">...</failure>
+//       <failure message="...">...</failure>
+//                                     <-- individual assertion failures
+//     </testcase>
+//   </testsuite>
+// </testsuites>
+
+// Formats the given time in milliseconds as seconds.
+std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {
+  ::std::stringstream ss;
+  ss << ms/1000.0;
+  return ss.str();
+}
+
+// Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
+void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream,
+                                                     const char* data) {
+  const char* segment = data;
+  *stream << "<![CDATA[";
+  for (;;) {
+    const char* const next_segment = strstr(segment, "]]>");
+    if (next_segment != NULL) {
+      stream->write(
+          segment, static_cast<std::streamsize>(next_segment - segment));
+      *stream << "]]>]]&gt;<![CDATA[";
+      segment = next_segment + strlen("]]>");
+    } else {
+      *stream << segment;
+      break;
+    }
+  }
+  *stream << "]]>";
+}
+
+// Prints an XML representation of a TestInfo object.
+// TODO(wan): There is also value in printing properties with the plain printer.
+void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
+                                                 const char* test_case_name,
+                                                 const TestInfo& test_info) {
+  const TestResult& result = *test_info.result();
+  *stream << "    <testcase name=\""
+          << EscapeXmlAttribute(test_info.name()).c_str()
+          << "\" status=\""
+          << (test_info.should_run() ? "run" : "notrun")
+          << "\" time=\""
+          << FormatTimeInMillisAsSeconds(result.elapsed_time())
+          << "\" classname=\"" << EscapeXmlAttribute(test_case_name).c_str()
+          << "\"" << TestPropertiesAsXmlAttributes(result).c_str();
+
+  int failures = 0;
+  for (int i = 0; i < result.total_part_count(); ++i) {
+    const TestPartResult& part = result.GetTestPartResult(i);
+    if (part.failed()) {
+      if (++failures == 1)
+        *stream << ">\n";
+      *stream << "      <failure message=\""
+              << EscapeXmlAttribute(part.summary()).c_str()
+              << "\" type=\"\">";
+      const String message = RemoveInvalidXmlCharacters(String::Format(
+          "%s:%d\n%s",
+          part.file_name(), part.line_number(),
+          part.message()).c_str());
+      OutputXmlCDataSection(stream, message.c_str());
+      *stream << "</failure>\n";
+    }
+  }
+
+  if (failures == 0)
+    *stream << " />\n";
+  else
+    *stream << "    </testcase>\n";
+}
+
+// Prints an XML representation of a TestCase object
+void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out,
+                                                const TestCase& test_case) {
+  fprintf(out,
+          "  <testsuite name=\"%s\" tests=\"%d\" failures=\"%d\" "
+          "disabled=\"%d\" ",
+          EscapeXmlAttribute(test_case.name()).c_str(),
+          test_case.total_test_count(),
+          test_case.failed_test_count(),
+          test_case.disabled_test_count());
+  fprintf(out,
+          "errors=\"0\" time=\"%s\">\n",
+          FormatTimeInMillisAsSeconds(test_case.elapsed_time()).c_str());
+  for (int i = 0; i < test_case.total_test_count(); ++i) {
+    StrStream stream;
+    OutputXmlTestInfo(&stream, test_case.name(), *test_case.GetTestInfo(i));
+    fprintf(out, "%s", StrStreamToString(&stream).c_str());
+  }
+  fprintf(out, "  </testsuite>\n");
+}
+
+// Prints an XML summary of unit_test to output stream out.
+void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out,
+                                                const UnitTest& unit_test) {
+  fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+  fprintf(out,
+          "<testsuites tests=\"%d\" failures=\"%d\" disabled=\"%d\" "
+          "errors=\"0\" time=\"%s\" ",
+          unit_test.total_test_count(),
+          unit_test.failed_test_count(),
+          unit_test.disabled_test_count(),
+          FormatTimeInMillisAsSeconds(unit_test.elapsed_time()).c_str());
+  if (GTEST_FLAG(shuffle)) {
+    fprintf(out, "random_seed=\"%d\" ", unit_test.random_seed());
+  }
+  fprintf(out, "name=\"AllTests\">\n");
+  for (int i = 0; i < unit_test.total_test_case_count(); ++i)
+    PrintXmlTestCase(out, *unit_test.GetTestCase(i));
+  fprintf(out, "</testsuites>\n");
+}
+
+// Produces a string representing the test properties in a result as space
+// delimited XML attributes based on the property key="value" pairs.
+String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
+    const TestResult& result) {
+  Message attributes;
+  for (int i = 0; i < result.test_property_count(); ++i) {
+    const TestProperty& property = result.GetTestProperty(i);
+    attributes << " " << property.key() << "="
+        << "\"" << EscapeXmlAttribute(property.value()) << "\"";
+  }
+  return attributes.GetString();
+}
+
+// End XmlUnitTestResultPrinter
+
+// Class ScopedTrace
+
+// Pushes the given source file location and message onto a per-thread
+// trace stack maintained by Google Test.
+// L < UnitTest::mutex_
+ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) {
+  TraceInfo trace;
+  trace.file = file;
+  trace.line = line;
+  trace.message = message.GetString();
+
+  UnitTest::GetInstance()->PushGTestTrace(trace);
+}
+
+// Pops the info pushed by the c'tor.
+// L < UnitTest::mutex_
+ScopedTrace::~ScopedTrace() {
+  UnitTest::GetInstance()->PopGTestTrace();
+}
+
+
+// class OsStackTraceGetter
+
+// Returns the current OS stack trace as a String.  Parameters:
+//
+//   max_depth  - the maximum number of stack frames to be included
+//                in the trace.
+//   skip_count - the number of top frames to be skipped; doesn't count
+//                against max_depth.
+//
+// L < mutex_
+// We use "L < mutex_" to denote that the function may acquire mutex_.
+String OsStackTraceGetter::CurrentStackTrace(int, int) {
+  return String("");
+}
+
+// L < mutex_
+void OsStackTraceGetter::UponLeavingGTest() {
+}
+
+const char* const
+OsStackTraceGetter::kElidedFramesMarker =
+    "... " GTEST_NAME_ " internal frames ...";
+
+}  // namespace internal
+
+// class TestEventListeners
+
+TestEventListeners::TestEventListeners()
+    : repeater_(new internal::TestEventRepeater()),
+      default_result_printer_(NULL),
+      default_xml_generator_(NULL) {
+}
+
+TestEventListeners::~TestEventListeners() { delete repeater_; }
+
+// Returns the standard listener responsible for the default console
+// output.  Can be removed from the listeners list to shut down default
+// console output.  Note that removing this object from the listener list
+// with Release transfers its ownership to the user.
+void TestEventListeners::Append(TestEventListener* listener) {
+  repeater_->Append(listener);
+}
+
+// Removes the given event listener from the list and returns it.  It then
+// becomes the caller's responsibility to delete the listener. Returns
+// NULL if the listener is not found in the list.
+TestEventListener* TestEventListeners::Release(TestEventListener* listener) {
+  if (listener == default_result_printer_)
+    default_result_printer_ = NULL;
+  else if (listener == default_xml_generator_)
+    default_xml_generator_ = NULL;
+  return repeater_->Release(listener);
+}
+
+// Returns repeater that broadcasts the TestEventListener events to all
+// subscribers.
+TestEventListener* TestEventListeners::repeater() { return repeater_; }
+
+// Sets the default_result_printer attribute to the provided listener.
+// The listener is also added to the listener list and previous
+// default_result_printer is removed from it and deleted. The listener can
+// also be NULL in which case it will not be added to the list. Does
+// nothing if the previous and the current listener objects are the same.
+void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) {
+  if (default_result_printer_ != listener) {
+    // It is an error to pass this method a listener that is already in the
+    // list.
+    delete Release(default_result_printer_);
+    default_result_printer_ = listener;
+    if (listener != NULL)
+      Append(listener);
+  }
+}
+
+// Sets the default_xml_generator attribute to the provided listener.  The
+// listener is also added to the listener list and previous
+// default_xml_generator is removed from it and deleted. The listener can
+// also be NULL in which case it will not be added to the list. Does
+// nothing if the previous and the current listener objects are the same.
+void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) {
+  if (default_xml_generator_ != listener) {
+    // It is an error to pass this method a listener that is already in the
+    // list.
+    delete Release(default_xml_generator_);
+    default_xml_generator_ = listener;
+    if (listener != NULL)
+      Append(listener);
+  }
+}
+
+// Controls whether events will be forwarded by the repeater to the
+// listeners in the list.
+bool TestEventListeners::EventForwardingEnabled() const {
+  return repeater_->forwarding_enabled();
+}
+
+void TestEventListeners::SuppressEventForwarding() {
+  repeater_->set_forwarding_enabled(false);
+}
+
+// class UnitTest
+
+// Gets the singleton UnitTest object.  The first time this method is
+// called, a UnitTest object is constructed and returned.  Consecutive
+// calls will return the same object.
+//
+// We don't protect this under mutex_ as a user is not supposed to
+// call this before main() starts, from which point on the return
+// value will never change.
+UnitTest * UnitTest::GetInstance() {
+  // When compiled with MSVC 7.1 in optimized mode, destroying the
+  // UnitTest object upon exiting the program messes up the exit code,
+  // causing successful tests to appear failed.  We have to use a
+  // different implementation in this case to bypass the compiler bug.
+  // This implementation makes the compiler happy, at the cost of
+  // leaking the UnitTest object.
+
+  // CodeGear C++Builder insists on a public destructor for the
+  // default implementation.  Use this implementation to keep good OO
+  // design with private destructor.
+
+#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)
+  static UnitTest* const instance = new UnitTest;
+  return instance;
+#else
+  static UnitTest instance;
+  return &instance;
+#endif  // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)
+}
+
+// Gets the number of successful test cases.
+int UnitTest::successful_test_case_count() const {
+  return impl()->successful_test_case_count();
+}
+
+// Gets the number of failed test cases.
+int UnitTest::failed_test_case_count() const {
+  return impl()->failed_test_case_count();
+}
+
+// Gets the number of all test cases.
+int UnitTest::total_test_case_count() const {
+  return impl()->total_test_case_count();
+}
+
+// Gets the number of all test cases that contain at least one test
+// that should run.
+int UnitTest::test_case_to_run_count() const {
+  return impl()->test_case_to_run_count();
+}
+
+// Gets the number of successful tests.
+int UnitTest::successful_test_count() const {
+  return impl()->successful_test_count();
+}
+
+// Gets the number of failed tests.
+int UnitTest::failed_test_count() const { return impl()->failed_test_count(); }
+
+// Gets the number of disabled tests.
+int UnitTest::disabled_test_count() const {
+  return impl()->disabled_test_count();
+}
+
+// Gets the number of all tests.
+int UnitTest::total_test_count() const { return impl()->total_test_count(); }
+
+// Gets the number of tests that should run.
+int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); }
+
+// Gets the elapsed time, in milliseconds.
+internal::TimeInMillis UnitTest::elapsed_time() const {
+  return impl()->elapsed_time();
+}
+
+// Returns true iff the unit test passed (i.e. all test cases passed).
+bool UnitTest::Passed() const { return impl()->Passed(); }
+
+// Returns true iff the unit test failed (i.e. some test case failed
+// or something outside of all tests failed).
+bool UnitTest::Failed() const { return impl()->Failed(); }
+
+// Gets the i-th test case among all the test cases. i can range from 0 to
+// total_test_case_count() - 1. If i is not in that range, returns NULL.
+const TestCase* UnitTest::GetTestCase(int i) const {
+  return impl()->GetTestCase(i);
+}
+
+// Gets the i-th test case among all the test cases. i can range from 0 to
+// total_test_case_count() - 1. If i is not in that range, returns NULL.
+TestCase* UnitTest::GetMutableTestCase(int i) {
+  return impl()->GetMutableTestCase(i);
+}
+
+// Returns the list of event listeners that can be used to track events
+// inside Google Test.
+TestEventListeners& UnitTest::listeners() {
+  return *impl()->listeners();
+}
+
+// Registers and returns a global test environment.  When a test
+// program is run, all global test environments will be set-up in the
+// order they were registered.  After all tests in the program have
+// finished, all global test environments will be torn-down in the
+// *reverse* order they were registered.
+//
+// The UnitTest object takes ownership of the given environment.
+//
+// We don't protect this under mutex_, as we only support calling it
+// from the main thread.
+Environment* UnitTest::AddEnvironment(Environment* env) {
+  if (env == NULL) {
+    return NULL;
+  }
+
+  impl_->environments().push_back(env);
+  return env;
+}
+
+#if GTEST_HAS_EXCEPTIONS
+// A failed Google Test assertion will throw an exception of this type
+// when exceptions are enabled.  We derive it from std::runtime_error,
+// which is for errors presumably detectable only at run time.  Since
+// std::runtime_error inherits from std::exception, many testing
+// frameworks know how to extract and print the message inside it.
+class GoogleTestFailureException : public ::std::runtime_error {
+ public:
+  explicit GoogleTestFailureException(const TestPartResult& failure)
+      : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {}
+};
+#endif
+
+// Adds a TestPartResult to the current TestResult object.  All Google Test
+// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call
+// this to report their results.  The user code should use the
+// assertion macros instead of calling this directly.
+// L < mutex_
+void UnitTest::AddTestPartResult(TestPartResult::Type result_type,
+                                 const char* file_name,
+                                 int line_number,
+                                 const internal::String& message,
+                                 const internal::String& os_stack_trace) {
+  Message msg;
+  msg << message;
+
+  internal::MutexLock lock(&mutex_);
+  if (impl_->gtest_trace_stack().size() > 0) {
+    msg << "\n" << GTEST_NAME_ << " trace:";
+
+    for (int i = static_cast<int>(impl_->gtest_trace_stack().size());
+         i > 0; --i) {
+      const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1];
+      msg << "\n" << internal::FormatFileLocation(trace.file, trace.line)
+          << " " << trace.message;
+    }
+  }
+
+  if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) {
+    msg << internal::kStackTraceMarker << os_stack_trace;
+  }
+
+  const TestPartResult result =
+    TestPartResult(result_type, file_name, line_number,
+                   msg.GetString().c_str());
+  impl_->GetTestPartResultReporterForCurrentThread()->
+      ReportTestPartResult(result);
+
+  if (result_type != TestPartResult::kSuccess) {
+    // gtest_break_on_failure takes precedence over
+    // gtest_throw_on_failure.  This allows a user to set the latter
+    // in the code (perhaps in order to use Google Test assertions
+    // with another testing framework) and specify the former on the
+    // command line for debugging.
+    if (GTEST_FLAG(break_on_failure)) {
+#if GTEST_OS_WINDOWS
+      // Using DebugBreak on Windows allows gtest to still break into a debugger
+      // when a failure happens and both the --gtest_break_on_failure and
+      // the --gtest_catch_exceptions flags are specified.
+      DebugBreak();
+#else
+      abort();
+#endif  // GTEST_OS_WINDOWS
+    } else if (GTEST_FLAG(throw_on_failure)) {
+#if GTEST_HAS_EXCEPTIONS
+      throw GoogleTestFailureException(result);
+#else
+      // We cannot call abort() as it generates a pop-up in debug mode
+      // that cannot be suppressed in VC 7.1 or below.
+      exit(1);
+#endif
+    }
+  }
+}
+
+// Creates and adds a property to the current TestResult. If a property matching
+// the supplied value already exists, updates its value instead.
+void UnitTest::RecordPropertyForCurrentTest(const char* key,
+                                            const char* value) {
+  const TestProperty test_property(key, value);
+  impl_->current_test_result()->RecordProperty(test_property);
+}
+
+// Runs all tests in this UnitTest object and prints the result.
+// Returns 0 if successful, or 1 otherwise.
+//
+// We don't protect this under mutex_, as we only support calling it
+// from the main thread.
+int UnitTest::Run() {
+#if GTEST_HAS_SEH
+  // Catch SEH-style exceptions.
+
+  const bool in_death_test_child_process =
+      internal::GTEST_FLAG(internal_run_death_test).length() > 0;
+
+  // Either the user wants Google Test to catch exceptions thrown by the
+  // tests or this is executing in the context of death test child
+  // process. In either case the user does not want to see pop-up dialogs
+  // about crashes - they are expected..
+  if (GTEST_FLAG(catch_exceptions) || in_death_test_child_process) {
+#if !GTEST_OS_WINDOWS_MOBILE
+    // SetErrorMode doesn't exist on CE.
+    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
+                 SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
+#endif  // !GTEST_OS_WINDOWS_MOBILE
+
+#if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE
+    // Death test children can be terminated with _abort().  On Windows,
+    // _abort() can show a dialog with a warning message.  This forces the
+    // abort message to go to stderr instead.
+    _set_error_mode(_OUT_TO_STDERR);
+#endif
+
+#if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE
+    // In the debug version, Visual Studio pops up a separate dialog
+    // offering a choice to debug the aborted program. We need to suppress
+    // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement
+    // executed. Google Test will notify the user of any unexpected
+    // failure via stderr.
+    //
+    // VC++ doesn't define _set_abort_behavior() prior to the version 8.0.
+    // Users of prior VC versions shall suffer the agony and pain of
+    // clicking through the countless debug dialogs.
+    // TODO(vladl@google.com): find a way to suppress the abort dialog() in the
+    // debug mode when compiled with VC 7.1 or lower.
+    if (!GTEST_FLAG(break_on_failure))
+      _set_abort_behavior(
+          0x0,                                    // Clear the following flags:
+          _WRITE_ABORT_MSG | _CALL_REPORTFAULT);  // pop-up window, core dump.
+#endif
+  }
+
+  __try {
+    return impl_->RunAllTests();
+  } __except(internal::UnitTestOptions::GTestShouldProcessSEH(
+      GetExceptionCode())) {
+    printf("Exception thrown with code 0x%x.\nFAIL\n", GetExceptionCode());
+    fflush(stdout);
+    return 1;
+  }
+
+#else  // We are on a compiler or platform that doesn't support SEH.
+
+  return impl_->RunAllTests();
+#endif  // GTEST_HAS_SEH
+}
+
+// Returns the working directory when the first TEST() or TEST_F() was
+// executed.
+const char* UnitTest::original_working_dir() const {
+  return impl_->original_working_dir_.c_str();
+}
+
+// Returns the TestCase object for the test that's currently running,
+// or NULL if no test is running.
+// L < mutex_
+const TestCase* UnitTest::current_test_case() const {
+  internal::MutexLock lock(&mutex_);
+  return impl_->current_test_case();
+}
+
+// Returns the TestInfo object for the test that's currently running,
+// or NULL if no test is running.
+// L < mutex_
+const TestInfo* UnitTest::current_test_info() const {
+  internal::MutexLock lock(&mutex_);
+  return impl_->current_test_info();
+}
+
+// Returns the random seed used at the start of the current test run.
+int UnitTest::random_seed() const { return impl_->random_seed(); }
+
+#if GTEST_HAS_PARAM_TEST
+// Returns ParameterizedTestCaseRegistry object used to keep track of
+// value-parameterized tests and instantiate and register them.
+// L < mutex_
+internal::ParameterizedTestCaseRegistry&
+    UnitTest::parameterized_test_registry() {
+  return impl_->parameterized_test_registry();
+}
+#endif  // GTEST_HAS_PARAM_TEST
+
+// Creates an empty UnitTest.
+UnitTest::UnitTest() {
+  impl_ = new internal::UnitTestImpl(this);
+}
+
+// Destructor of UnitTest.
+UnitTest::~UnitTest() {
+  delete impl_;
+}
+
+// Pushes a trace defined by SCOPED_TRACE() on to the per-thread
+// Google Test trace stack.
+// L < mutex_
+void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) {
+  internal::MutexLock lock(&mutex_);
+  impl_->gtest_trace_stack().push_back(trace);
+}
+
+// Pops a trace from the per-thread Google Test trace stack.
+// L < mutex_
+void UnitTest::PopGTestTrace() {
+  internal::MutexLock lock(&mutex_);
+  impl_->gtest_trace_stack().pop_back();
+}
+
+namespace internal {
+
+UnitTestImpl::UnitTestImpl(UnitTest* parent)
+    : parent_(parent),
+#ifdef _MSC_VER
+#pragma warning(push)                    // Saves the current warning state.
+#pragma warning(disable:4355)            // Temporarily disables warning 4355
+                                         // (using this in initializer).
+      default_global_test_part_result_reporter_(this),
+      default_per_thread_test_part_result_reporter_(this),
+#pragma warning(pop)                     // Restores the warning state again.
+#else
+      default_global_test_part_result_reporter_(this),
+      default_per_thread_test_part_result_reporter_(this),
+#endif  // _MSC_VER
+      global_test_part_result_repoter_(
+          &default_global_test_part_result_reporter_),
+      per_thread_test_part_result_reporter_(
+          &default_per_thread_test_part_result_reporter_),
+#if GTEST_HAS_PARAM_TEST
+      parameterized_test_registry_(),
+      parameterized_tests_registered_(false),
+#endif  // GTEST_HAS_PARAM_TEST
+      last_death_test_case_(-1),
+      current_test_case_(NULL),
+      current_test_info_(NULL),
+      ad_hoc_test_result_(),
+      os_stack_trace_getter_(NULL),
+      post_flag_parse_init_performed_(false),
+      random_seed_(0),  // Will be overridden by the flag before first use.
+      random_(0),  // Will be reseeded before first use.
+#if GTEST_HAS_DEATH_TEST
+      elapsed_time_(0),
+      internal_run_death_test_flag_(NULL),
+      death_test_factory_(new DefaultDeathTestFactory) {
+#else
+      elapsed_time_(0) {
+#endif  // GTEST_HAS_DEATH_TEST
+  listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter);
+}
+
+UnitTestImpl::~UnitTestImpl() {
+  // Deletes every TestCase.
+  ForEach(test_cases_, internal::Delete<TestCase>);
+
+  // Deletes every Environment.
+  ForEach(environments_, internal::Delete<Environment>);
+
+  delete os_stack_trace_getter_;
+}
+
+#if GTEST_HAS_DEATH_TEST
+// Disables event forwarding if the control is currently in a death test
+// subprocess. Must not be called before InitGoogleTest.
+void UnitTestImpl::SuppressTestEventsIfInSubprocess() {
+  if (internal_run_death_test_flag_.get() != NULL)
+    listeners()->SuppressEventForwarding();
+}
+#endif  // GTEST_HAS_DEATH_TEST
+
+// Initializes event listeners performing XML output as specified by
+// UnitTestOptions. Must not be called before InitGoogleTest.
+void UnitTestImpl::ConfigureXmlOutput() {
+  const String& output_format = UnitTestOptions::GetOutputFormat();
+  if (output_format == "xml") {
+    listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(
+        UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
+  } else if (output_format != "") {
+    printf("WARNING: unrecognized output format \"%s\" ignored.\n",
+           output_format.c_str());
+    fflush(stdout);
+  }
+}
+
+// Performs initialization dependent upon flag values obtained in
+// ParseGoogleTestFlagsOnly.  Is called from InitGoogleTest after the call to
+// ParseGoogleTestFlagsOnly.  In case a user neglects to call InitGoogleTest
+// this function is also called from RunAllTests.  Since this function can be
+// called more than once, it has to be idempotent.
+void UnitTestImpl::PostFlagParsingInit() {
+  // Ensures that this function does not execute more than once.
+  if (!post_flag_parse_init_performed_) {
+    post_flag_parse_init_performed_ = true;
+
+#if GTEST_HAS_DEATH_TEST
+    InitDeathTestSubprocessControlInfo();
+    SuppressTestEventsIfInSubprocess();
+#endif  // GTEST_HAS_DEATH_TEST
+
+    // Registers parameterized tests. This makes parameterized tests
+    // available to the UnitTest reflection API without running
+    // RUN_ALL_TESTS.
+    RegisterParameterizedTests();
+
+    // Configures listeners for XML output. This makes it possible for users
+    // to shut down the default XML output before invoking RUN_ALL_TESTS.
+    ConfigureXmlOutput();
+  }
+}
+
+// A predicate that checks the name of a TestCase against a known
+// value.
+//
+// This is used for implementation of the UnitTest class only.  We put
+// it in the anonymous namespace to prevent polluting the outer
+// namespace.
+//
+// TestCaseNameIs is copyable.
+class TestCaseNameIs {
+ public:
+  // Constructor.
+  explicit TestCaseNameIs(const String& name)
+      : name_(name) {}
+
+  // Returns true iff the name of test_case matches name_.
+  bool operator()(const TestCase* test_case) const {
+    return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0;
+  }
+
+ private:
+  String name_;
+};
+
+// Finds and returns a TestCase with the given name.  If one doesn't
+// exist, creates one and returns it.  It's the CALLER'S
+// RESPONSIBILITY to ensure that this function is only called WHEN THE
+// TESTS ARE NOT SHUFFLED.
+//
+// Arguments:
+//
+//   test_case_name: name of the test case
+//   set_up_tc:      pointer to the function that sets up the test case
+//   tear_down_tc:   pointer to the function that tears down the test case
+TestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
+                                    const char* comment,
+                                    Test::SetUpTestCaseFunc set_up_tc,
+                                    Test::TearDownTestCaseFunc tear_down_tc) {
+  // Can we find a TestCase with the given name?
+  const std::vector<TestCase*>::const_iterator test_case =
+      std::find_if(test_cases_.begin(), test_cases_.end(),
+                   TestCaseNameIs(test_case_name));
+
+  if (test_case != test_cases_.end())
+    return *test_case;
+
+  // No.  Let's create one.
+  TestCase* const new_test_case =
+      new TestCase(test_case_name, comment, set_up_tc, tear_down_tc);
+
+  // Is this a death test case?
+  if (internal::UnitTestOptions::MatchesFilter(String(test_case_name),
+                                               kDeathTestCaseFilter)) {
+    // Yes.  Inserts the test case after the last death test case
+    // defined so far.  This only works when the test cases haven't
+    // been shuffled.  Otherwise we may end up running a death test
+    // after a non-death test.
+    ++last_death_test_case_;
+    test_cases_.insert(test_cases_.begin() + last_death_test_case_,
+                       new_test_case);
+  } else {
+    // No.  Appends to the end of the list.
+    test_cases_.push_back(new_test_case);
+  }
+
+  test_case_indices_.push_back(static_cast<int>(test_case_indices_.size()));
+  return new_test_case;
+}
+
+// Helpers for setting up / tearing down the given environment.  They
+// are for use in the ForEach() function.
+static void SetUpEnvironment(Environment* env) { env->SetUp(); }
+static void TearDownEnvironment(Environment* env) { env->TearDown(); }
+
+// Runs all tests in this UnitTest object, prints the result, and
+// returns 0 if all tests are successful, or 1 otherwise.  If any
+// exception is thrown during a test on Windows, this test is
+// considered to be failed, but the rest of the tests will still be
+// run.  (We disable exceptions on Linux and Mac OS X, so the issue
+// doesn't apply there.)
+// When parameterized tests are enabled, it expands and registers
+// parameterized tests first in RegisterParameterizedTests().
+// All other functions called from RunAllTests() may safely assume that
+// parameterized tests are ready to be counted and run.
+int UnitTestImpl::RunAllTests() {
+  // Makes sure InitGoogleTest() was called.
+  if (!GTestIsInitialized()) {
+    printf("%s",
+           "\nThis test program did NOT call ::testing::InitGoogleTest "
+           "before calling RUN_ALL_TESTS().  Please fix it.\n");
+    return 1;
+  }
+
+  // Do not run any test if the --help flag was specified.
+  if (g_help_flag)
+    return 0;
+
+  // Repeats the call to the post-flag parsing initialization in case the
+  // user didn't call InitGoogleTest.
+  PostFlagParsingInit();
+
+  // Even if sharding is not on, test runners may want to use the
+  // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding
+  // protocol.
+  internal::WriteToShardStatusFileIfNeeded();
+
+  // True iff we are in a subprocess for running a thread-safe-style
+  // death test.
+  bool in_subprocess_for_death_test = false;
+
+#if GTEST_HAS_DEATH_TEST
+  in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL);
+#endif  // GTEST_HAS_DEATH_TEST
+
+  const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex,
+                                        in_subprocess_for_death_test);
+
+  // Compares the full test names with the filter to decide which
+  // tests to run.
+  const bool has_tests_to_run = FilterTests(should_shard
+                                              ? HONOR_SHARDING_PROTOCOL
+                                              : IGNORE_SHARDING_PROTOCOL) > 0;
+
+  // Lists the tests and exits if the --gtest_list_tests flag was specified.
+  if (GTEST_FLAG(list_tests)) {
+    // This must be called *after* FilterTests() has been called.
+    ListTestsMatchingFilter();
+    return 0;
+  }
+
+  random_seed_ = GTEST_FLAG(shuffle) ?
+      GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0;
+
+  // True iff at least one test has failed.
+  bool failed = false;
+
+  TestEventListener* repeater = listeners()->repeater();
+
+  repeater->OnTestProgramStart(*parent_);
+
+  // How many times to repeat the tests?  We don't want to repeat them
+  // when we are inside the subprocess of a death test.
+  const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat);
+  // Repeats forever if the repeat count is negative.
+  const bool forever = repeat < 0;
+  for (int i = 0; forever || i != repeat; i++) {
+    ClearResult();
+
+    const TimeInMillis start = GetTimeInMillis();
+
+    // Shuffles test cases and tests if requested.
+    if (has_tests_to_run && GTEST_FLAG(shuffle)) {
+      random()->Reseed(random_seed_);
+      // This should be done before calling OnTestIterationStart(),
+      // such that a test event listener can see the actual test order
+      // in the event.
+      ShuffleTests();
+    }
+
+    // Tells the unit test event listeners that the tests are about to start.
+    repeater->OnTestIterationStart(*parent_, i);
+
+    // Runs each test case if there is at least one test to run.
+    if (has_tests_to_run) {
+      // Sets up all environments beforehand.
+      repeater->OnEnvironmentsSetUpStart(*parent_);
+      ForEach(environments_, SetUpEnvironment);
+      repeater->OnEnvironmentsSetUpEnd(*parent_);
+
+      // Runs the tests only if there was no fatal failure during global
+      // set-up.
+      if (!Test::HasFatalFailure()) {
+        for (int test_index = 0; test_index < total_test_case_count();
+             test_index++) {
+          GetMutableTestCase(test_index)->Run();
+        }
+      }
+
+      // Tears down all environments in reverse order afterwards.
+      repeater->OnEnvironmentsTearDownStart(*parent_);
+      std::for_each(environments_.rbegin(), environments_.rend(),
+                    TearDownEnvironment);
+      repeater->OnEnvironmentsTearDownEnd(*parent_);
+    }
+
+    elapsed_time_ = GetTimeInMillis() - start;
+
+    // Tells the unit test event listener that the tests have just finished.
+    repeater->OnTestIterationEnd(*parent_, i);
+
+    // Gets the result and clears it.
+    if (!Passed()) {
+      failed = true;
+    }
+
+    // Restores the original test order after the iteration.  This
+    // allows the user to quickly repro a failure that happens in the
+    // N-th iteration without repeating the first (N - 1) iterations.
+    // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in
+    // case the user somehow changes the value of the flag somewhere
+    // (it's always safe to unshuffle the tests).
+    UnshuffleTests();
+
+    if (GTEST_FLAG(shuffle)) {
+      // Picks a new random seed for each iteration.
+      random_seed_ = GetNextRandomSeed(random_seed_);
+    }
+  }
+
+  repeater->OnTestProgramEnd(*parent_);
+
+  // Returns 0 if all tests passed, or 1 other wise.
+  return failed ? 1 : 0;
+}
+
+// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file
+// if the variable is present. If a file already exists at this location, this
+// function will write over it. If the variable is present, but the file cannot
+// be created, prints an error and exits.
+void WriteToShardStatusFileIfNeeded() {
+  const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile);
+  if (test_shard_file != NULL) {
+    FILE* const file = posix::FOpen(test_shard_file, "w");
+    if (file == NULL) {
+      ColoredPrintf(COLOR_RED,
+                    "Could not write to the test shard status file \"%s\" "
+                    "specified by the %s environment variable.\n",
+                    test_shard_file, kTestShardStatusFile);
+      fflush(stdout);
+      exit(EXIT_FAILURE);
+    }
+    fclose(file);
+  }
+}
+
+// Checks whether sharding is enabled by examining the relevant
+// environment variable values. If the variables are present,
+// but inconsistent (i.e., shard_index >= total_shards), prints
+// an error and exits. If in_subprocess_for_death_test, sharding is
+// disabled because it must only be applied to the original test
+// process. Otherwise, we could filter out death tests we intended to execute.
+bool ShouldShard(const char* total_shards_env,
+                 const char* shard_index_env,
+                 bool in_subprocess_for_death_test) {
+  if (in_subprocess_for_death_test) {
+    return false;
+  }
+
+  const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1);
+  const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1);
+
+  if (total_shards == -1 && shard_index == -1) {
+    return false;
+  } else if (total_shards == -1 && shard_index != -1) {
+    const Message msg = Message()
+      << "Invalid environment variables: you have "
+      << kTestShardIndex << " = " << shard_index
+      << ", but have left " << kTestTotalShards << " unset.\n";
+    ColoredPrintf(COLOR_RED, msg.GetString().c_str());
+    fflush(stdout);
+    exit(EXIT_FAILURE);
+  } else if (total_shards != -1 && shard_index == -1) {
+    const Message msg = Message()
+      << "Invalid environment variables: you have "
+      << kTestTotalShards << " = " << total_shards
+      << ", but have left " << kTestShardIndex << " unset.\n";
+    ColoredPrintf(COLOR_RED, msg.GetString().c_str());
+    fflush(stdout);
+    exit(EXIT_FAILURE);
+  } else if (shard_index < 0 || shard_index >= total_shards) {
+    const Message msg = Message()
+      << "Invalid environment variables: we require 0 <= "
+      << kTestShardIndex << " < " << kTestTotalShards
+      << ", but you have " << kTestShardIndex << "=" << shard_index
+      << ", " << kTestTotalShards << "=" << total_shards << ".\n";
+    ColoredPrintf(COLOR_RED, msg.GetString().c_str());
+    fflush(stdout);
+    exit(EXIT_FAILURE);
+  }
+
+  return total_shards > 1;
+}
+
+// Parses the environment variable var as an Int32. If it is unset,
+// returns default_val. If it is not an Int32, prints an error
+// and aborts.
+Int32 Int32FromEnvOrDie(const char* const var, Int32 default_val) {
+  const char* str_val = posix::GetEnv(var);
+  if (str_val == NULL) {
+    return default_val;
+  }
+
+  Int32 result;
+  if (!ParseInt32(Message() << "The value of environment variable " << var,
+                  str_val, &result)) {
+    exit(EXIT_FAILURE);
+  }
+  return result;
+}
+
+// Given the total number of shards, the shard index, and the test id,
+// returns true iff the test should be run on this shard. The test id is
+// some arbitrary but unique non-negative integer assigned to each test
+// method. Assumes that 0 <= shard_index < total_shards.
+bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) {
+  return (test_id % total_shards) == shard_index;
+}
+
+// Compares the name of each test with the user-specified filter to
+// decide whether the test should be run, then records the result in
+// each TestCase and TestInfo object.
+// If shard_tests == true, further filters tests based on sharding
+// variables in the environment - see
+// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide.
+// Returns the number of tests that should run.
+int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
+  const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ?
+      Int32FromEnvOrDie(kTestTotalShards, -1) : -1;
+  const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ?
+      Int32FromEnvOrDie(kTestShardIndex, -1) : -1;
+
+  // num_runnable_tests are the number of tests that will
+  // run across all shards (i.e., match filter and are not disabled).
+  // num_selected_tests are the number of tests to be run on
+  // this shard.
+  int num_runnable_tests = 0;
+  int num_selected_tests = 0;
+  for (size_t i = 0; i < test_cases_.size(); i++) {
+    TestCase* const test_case = test_cases_[i];
+    const String &test_case_name = test_case->name();
+    test_case->set_should_run(false);
+
+    for (size_t j = 0; j < test_case->test_info_list().size(); j++) {
+      TestInfo* const test_info = test_case->test_info_list()[j];
+      const String test_name(test_info->name());
+      // A test is disabled if test case name or test name matches
+      // kDisableTestFilter.
+      const bool is_disabled =
+          internal::UnitTestOptions::MatchesFilter(test_case_name,
+                                                   kDisableTestFilter) ||
+          internal::UnitTestOptions::MatchesFilter(test_name,
+                                                   kDisableTestFilter);
+      test_info->impl()->set_is_disabled(is_disabled);
+
+      const bool matches_filter =
+          internal::UnitTestOptions::FilterMatchesTest(test_case_name,
+                                                       test_name);
+      test_info->impl()->set_matches_filter(matches_filter);
+
+      const bool is_runnable =
+          (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) &&
+          matches_filter;
+
+      const bool is_selected = is_runnable &&
+          (shard_tests == IGNORE_SHARDING_PROTOCOL ||
+           ShouldRunTestOnShard(total_shards, shard_index,
+                                num_runnable_tests));
+
+      num_runnable_tests += is_runnable;
+      num_selected_tests += is_selected;
+
+      test_info->impl()->set_should_run(is_selected);
+      test_case->set_should_run(test_case->should_run() || is_selected);
+    }
+  }
+  return num_selected_tests;
+}
+
+// Prints the names of the tests matching the user-specified filter flag.
+void UnitTestImpl::ListTestsMatchingFilter() {
+  for (size_t i = 0; i < test_cases_.size(); i++) {
+    const TestCase* const test_case = test_cases_[i];
+    bool printed_test_case_name = false;
+
+    for (size_t j = 0; j < test_case->test_info_list().size(); j++) {
+      const TestInfo* const test_info =
+          test_case->test_info_list()[j];
+      if (test_info->matches_filter()) {
+        if (!printed_test_case_name) {
+          printed_test_case_name = true;
+          printf("%s.\n", test_case->name());
+        }
+        printf("  %s\n", test_info->name());
+      }
+    }
+  }
+  fflush(stdout);
+}
+
+// Sets the OS stack trace getter.
+//
+// Does nothing if the input and the current OS stack trace getter are
+// the same; otherwise, deletes the old getter and makes the input the
+// current getter.
+void UnitTestImpl::set_os_stack_trace_getter(
+    OsStackTraceGetterInterface* getter) {
+  if (os_stack_trace_getter_ != getter) {
+    delete os_stack_trace_getter_;
+    os_stack_trace_getter_ = getter;
+  }
+}
+
+// Returns the current OS stack trace getter if it is not NULL;
+// otherwise, creates an OsStackTraceGetter, makes it the current
+// getter, and returns it.
+OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() {
+  if (os_stack_trace_getter_ == NULL) {
+    os_stack_trace_getter_ = new OsStackTraceGetter;
+  }
+
+  return os_stack_trace_getter_;
+}
+
+// Returns the TestResult for the test that's currently running, or
+// the TestResult for the ad hoc test if no test is running.
+TestResult* UnitTestImpl::current_test_result() {
+  return current_test_info_ ?
+    current_test_info_->impl()->result() : &ad_hoc_test_result_;
+}
+
+// Shuffles all test cases, and the tests within each test case,
+// making sure that death tests are still run first.
+void UnitTestImpl::ShuffleTests() {
+  // Shuffles the death test cases.
+  ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_);
+
+  // Shuffles the non-death test cases.
+  ShuffleRange(random(), last_death_test_case_ + 1,
+               static_cast<int>(test_cases_.size()), &test_case_indices_);
+
+  // Shuffles the tests inside each test case.
+  for (size_t i = 0; i < test_cases_.size(); i++) {
+    test_cases_[i]->ShuffleTests(random());
+  }
+}
+
+// Restores the test cases and tests to their order before the first shuffle.
+void UnitTestImpl::UnshuffleTests() {
+  for (size_t i = 0; i < test_cases_.size(); i++) {
+    // Unshuffles the tests in each test case.
+    test_cases_[i]->UnshuffleTests();
+    // Resets the index of each test case.
+    test_case_indices_[i] = static_cast<int>(i);
+  }
+}
+
+// TestInfoImpl constructor. The new instance assumes ownership of the test
+// factory object.
+TestInfoImpl::TestInfoImpl(TestInfo* parent,
+                           const char* a_test_case_name,
+                           const char* a_name,
+                           const char* a_test_case_comment,
+                           const char* a_comment,
+                           TypeId a_fixture_class_id,
+                           internal::TestFactoryBase* factory) :
+    parent_(parent),
+    test_case_name_(String(a_test_case_name)),
+    name_(String(a_name)),
+    test_case_comment_(String(a_test_case_comment)),
+    comment_(String(a_comment)),
+    fixture_class_id_(a_fixture_class_id),
+    should_run_(false),
+    is_disabled_(false),
+    matches_filter_(false),
+    factory_(factory) {
+}
+
+// TestInfoImpl destructor.
+TestInfoImpl::~TestInfoImpl() {
+  delete factory_;
+}
+
+// Returns the current OS stack trace as a String.
+//
+// The maximum number of stack frames to be included is specified by
+// the gtest_stack_trace_depth flag.  The skip_count parameter
+// specifies the number of top frames to be skipped, which doesn't
+// count against the number of frames to be included.
+//
+// For example, if Foo() calls Bar(), which in turn calls
+// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
+// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
+String GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/,
+                                       int skip_count) {
+  // We pass skip_count + 1 to skip this wrapper function in addition
+  // to what the user really wants to skip.
+  return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1);
+}
+
+// Used by the GTEST_HIDE_UNREACHABLE_CODE_ macro to suppress unreachable
+// code warnings.
+namespace {
+class ClassUniqueToAlwaysTrue {};
+}
+
+bool IsTrue(bool condition) { return condition; }
+
+bool AlwaysTrue() {
+#if GTEST_HAS_EXCEPTIONS
+  // This condition is always false so AlwaysTrue() never actually throws,
+  // but it makes the compiler think that it may throw.
+  if (IsTrue(false))
+    throw ClassUniqueToAlwaysTrue();
+#endif  // GTEST_HAS_EXCEPTIONS
+  return true;
+}
+
+// If *pstr starts with the given prefix, modifies *pstr to be right
+// past the prefix and returns true; otherwise leaves *pstr unchanged
+// and returns false.  None of pstr, *pstr, and prefix can be NULL.
+bool SkipPrefix(const char* prefix, const char** pstr) {
+  const size_t prefix_len = strlen(prefix);
+  if (strncmp(*pstr, prefix, prefix_len) == 0) {
+    *pstr += prefix_len;
+    return true;
+  }
+  return false;
+}
+
+// Parses a string as a command line flag.  The string should have
+// the format "--flag=value".  When def_optional is true, the "=value"
+// part can be omitted.
+//
+// Returns the value of the flag, or NULL if the parsing failed.
+const char* ParseFlagValue(const char* str,
+                           const char* flag,
+                           bool def_optional) {
+  // str and flag must not be NULL.
+  if (str == NULL || flag == NULL) return NULL;
+
+  // The flag must start with "--" followed by GTEST_FLAG_PREFIX_.
+  const String flag_str = String::Format("--%s%s", GTEST_FLAG_PREFIX_, flag);
+  const size_t flag_len = flag_str.length();
+  if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;
+
+  // Skips the flag name.
+  const char* flag_end = str + flag_len;
+
+  // When def_optional is true, it's OK to not have a "=value" part.
+  if (def_optional && (flag_end[0] == '\0')) {
+    return flag_end;
+  }
+
+  // If def_optional is true and there are more characters after the
+  // flag name, or if def_optional is false, there must be a '=' after
+  // the flag name.
+  if (flag_end[0] != '=') return NULL;
+
+  // Returns the string after "=".
+  return flag_end + 1;
+}
+
+// Parses a string for a bool flag, in the form of either
+// "--flag=value" or "--flag".
+//
+// In the former case, the value is taken as true as long as it does
+// not start with '0', 'f', or 'F'.
+//
+// In the latter case, the value is taken as true.
+//
+// On success, stores the value of the flag in *value, and returns
+// true.  On failure, returns false without changing *value.
+bool ParseBoolFlag(const char* str, const char* flag, bool* value) {
+  // Gets the value of the flag as a string.
+  const char* const value_str = ParseFlagValue(str, flag, true);
+
+  // Aborts if the parsing failed.
+  if (value_str == NULL) return false;
+
+  // Converts the string value to a bool.
+  *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');
+  return true;
+}
+
+// Parses a string for an Int32 flag, in the form of
+// "--flag=value".
+//
+// On success, stores the value of the flag in *value, and returns
+// true.  On failure, returns false without changing *value.
+bool ParseInt32Flag(const char* str, const char* flag, Int32* value) {
+  // Gets the value of the flag as a string.
+  const char* const value_str = ParseFlagValue(str, flag, false);
+
+  // Aborts if the parsing failed.
+  if (value_str == NULL) return false;
+
+  // Sets *value to the value of the flag.
+  return ParseInt32(Message() << "The value of flag --" << flag,
+                    value_str, value);
+}
+
+// Parses a string for a string flag, in the form of
+// "--flag=value".
+//
+// On success, stores the value of the flag in *value, and returns
+// true.  On failure, returns false without changing *value.
+bool ParseStringFlag(const char* str, const char* flag, String* value) {
+  // Gets the value of the flag as a string.
+  const char* const value_str = ParseFlagValue(str, flag, false);
+
+  // Aborts if the parsing failed.
+  if (value_str == NULL) return false;
+
+  // Sets *value to the value of the flag.
+  *value = value_str;
+  return true;
+}
+
+// Determines whether a string has a prefix that Google Test uses for its
+// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_.
+// If Google Test detects that a command line flag has its prefix but is not
+// recognized, it will print its help message. Flags starting with
+// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test
+// internal flags and do not trigger the help message.
+static bool HasGoogleTestFlagPrefix(const char* str) {
+  return (SkipPrefix("--", &str) ||
+          SkipPrefix("-", &str) ||
+          SkipPrefix("/", &str)) &&
+         !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) &&
+         (SkipPrefix(GTEST_FLAG_PREFIX_, &str) ||
+          SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str));
+}
+
+// Prints a string containing code-encoded text.  The following escape
+// sequences can be used in the string to control the text color:
+//
+//   @@    prints a single '@' character.
+//   @R    changes the color to red.
+//   @G    changes the color to green.
+//   @Y    changes the color to yellow.
+//   @D    changes to the default terminal text color.
+//
+// TODO(wan@google.com): Write tests for this once we add stdout
+// capturing to Google Test.
+static void PrintColorEncoded(const char* str) {
+  GTestColor color = COLOR_DEFAULT;  // The current color.
+
+  // Conceptually, we split the string into segments divided by escape
+  // sequences.  Then we print one segment at a time.  At the end of
+  // each iteration, the str pointer advances to the beginning of the
+  // next segment.
+  for (;;) {
+    const char* p = strchr(str, '@');
+    if (p == NULL) {
+      ColoredPrintf(color, "%s", str);
+      return;
+    }
+
+    ColoredPrintf(color, "%s", String(str, p - str).c_str());
+
+    const char ch = p[1];
+    str = p + 2;
+    if (ch == '@') {
+      ColoredPrintf(color, "@");
+    } else if (ch == 'D') {
+      color = COLOR_DEFAULT;
+    } else if (ch == 'R') {
+      color = COLOR_RED;
+    } else if (ch == 'G') {
+      color = COLOR_GREEN;
+    } else if (ch == 'Y') {
+      color = COLOR_YELLOW;
+    } else {
+      --str;
+    }
+  }
+}
+
+static const char kColorEncodedHelpMessage[] =
+"This program contains tests written using " GTEST_NAME_ ". You can use the\n"
+"following command line flags to control its behavior:\n"
+"\n"
+"Test Selection:\n"
+"  @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n"
+"      List the names of all tests instead of running them. The name of\n"
+"      TEST(Foo, Bar) is \"Foo.Bar\".\n"
+"  @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS"
+    "[@G-@YNEGATIVE_PATTERNS]@D\n"
+"      Run only the tests whose name matches one of the positive patterns but\n"
+"      none of the negative patterns. '?' matches any single character; '*'\n"
+"      matches any substring; ':' separates two patterns.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n"
+"      Run all disabled tests too.\n"
+"\n"
+"Test Execution:\n"
+"  @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n"
+"      Run the tests repeatedly; use a negative count to repeat forever.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n"
+"      Randomize tests' orders on every iteration.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n"
+"      Random number seed to use for shuffling test orders (between 1 and\n"
+"      99999, or 0 to use a seed based on the current time).\n"
+"\n"
+"Test Output:\n"
+"  @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n"
+"      Enable/disable colored output. The default is @Gauto@D.\n"
+"  -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n"
+"      Don't print the elapsed time of each test.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G"
+    GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n"
+"      Generate an XML report in the given directory or with the given file\n"
+"      name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n"
+"\n"
+"Assertion Behavior:\n"
+#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
+"  @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n"
+"      Set the default death test style.\n"
+#endif  // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
+"  @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n"
+"      Turn assertion failures into debugger break-points.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n"
+"      Turn assertion failures into C++ exceptions.\n"
+#if GTEST_OS_WINDOWS
+"  @G--" GTEST_FLAG_PREFIX_ "catch_exceptions@D\n"
+"      Suppress pop-ups caused by exceptions.\n"
+#endif  // GTEST_OS_WINDOWS
+"\n"
+"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set "
+    "the corresponding\n"
+"environment variable of a flag (all letters in upper-case). For example, to\n"
+"disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_
+    "color=no@D or set\n"
+"the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n"
+"\n"
+"For more information, please read the " GTEST_NAME_ " documentation at\n"
+"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n"
+"(not one in your own code or tests), please report it to\n"
+"@G<" GTEST_DEV_EMAIL_ ">@D.\n";
+
+// Parses the command line for Google Test flags, without initializing
+// other parts of Google Test.  The type parameter CharType can be
+// instantiated to either char or wchar_t.
+template <typename CharType>
+void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
+  for (int i = 1; i < *argc; i++) {
+    const String arg_string = StreamableToString(argv[i]);
+    const char* const arg = arg_string.c_str();
+
+    using internal::ParseBoolFlag;
+    using internal::ParseInt32Flag;
+    using internal::ParseStringFlag;
+
+    // Do we see a Google Test flag?
+    if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag,
+                      &GTEST_FLAG(also_run_disabled_tests)) ||
+        ParseBoolFlag(arg, kBreakOnFailureFlag,
+                      &GTEST_FLAG(break_on_failure)) ||
+        ParseBoolFlag(arg, kCatchExceptionsFlag,
+                      &GTEST_FLAG(catch_exceptions)) ||
+        ParseStringFlag(arg, kColorFlag, &GTEST_FLAG(color)) ||
+        ParseStringFlag(arg, kDeathTestStyleFlag,
+                        &GTEST_FLAG(death_test_style)) ||
+        ParseBoolFlag(arg, kDeathTestUseFork,
+                      &GTEST_FLAG(death_test_use_fork)) ||
+        ParseStringFlag(arg, kFilterFlag, &GTEST_FLAG(filter)) ||
+        ParseStringFlag(arg, kInternalRunDeathTestFlag,
+                        &GTEST_FLAG(internal_run_death_test)) ||
+        ParseBoolFlag(arg, kListTestsFlag, &GTEST_FLAG(list_tests)) ||
+        ParseStringFlag(arg, kOutputFlag, &GTEST_FLAG(output)) ||
+        ParseBoolFlag(arg, kPrintTimeFlag, &GTEST_FLAG(print_time)) ||
+        ParseInt32Flag(arg, kRandomSeedFlag, &GTEST_FLAG(random_seed)) ||
+        ParseInt32Flag(arg, kRepeatFlag, &GTEST_FLAG(repeat)) ||
+        ParseBoolFlag(arg, kShuffleFlag, &GTEST_FLAG(shuffle)) ||
+        ParseInt32Flag(arg, kStackTraceDepthFlag,
+                       &GTEST_FLAG(stack_trace_depth)) ||
+        ParseBoolFlag(arg, kThrowOnFailureFlag, &GTEST_FLAG(throw_on_failure))
+        ) {
+      // Yes.  Shift the remainder of the argv list left by one.  Note
+      // that argv has (*argc + 1) elements, the last one always being
+      // NULL.  The following loop moves the trailing NULL element as
+      // well.
+      for (int j = i; j != *argc; j++) {
+        argv[j] = argv[j + 1];
+      }
+
+      // Decrements the argument count.
+      (*argc)--;
+
+      // We also need to decrement the iterator as we just removed
+      // an element.
+      i--;
+    } else if (arg_string == "--help" || arg_string == "-h" ||
+               arg_string == "-?" || arg_string == "/?" ||
+               HasGoogleTestFlagPrefix(arg)) {
+      // Both help flag and unrecognized Google Test flags (excluding
+      // internal ones) trigger help display.
+      g_help_flag = true;
+    }
+  }
+
+  if (g_help_flag) {
+    // We print the help here instead of in RUN_ALL_TESTS(), as the
+    // latter may not be called at all if the user is using Google
+    // Test with another testing framework.
+    PrintColorEncoded(kColorEncodedHelpMessage);
+  }
+}
+
+// Parses the command line for Google Test flags, without initializing
+// other parts of Google Test.
+void ParseGoogleTestFlagsOnly(int* argc, char** argv) {
+  ParseGoogleTestFlagsOnlyImpl(argc, argv);
+}
+void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) {
+  ParseGoogleTestFlagsOnlyImpl(argc, argv);
+}
+
+// The internal implementation of InitGoogleTest().
+//
+// The type parameter CharType can be instantiated to either char or
+// wchar_t.
+template <typename CharType>
+void InitGoogleTestImpl(int* argc, CharType** argv) {
+  g_init_gtest_count++;
+
+  // We don't want to run the initialization code twice.
+  if (g_init_gtest_count != 1) return;
+
+  if (*argc <= 0) return;
+
+  internal::g_executable_path = internal::StreamableToString(argv[0]);
+
+#if GTEST_HAS_DEATH_TEST
+  g_argvs.clear();
+  for (int i = 0; i != *argc; i++) {
+    g_argvs.push_back(StreamableToString(argv[i]));
+  }
+#endif  // GTEST_HAS_DEATH_TEST
+
+  ParseGoogleTestFlagsOnly(argc, argv);
+  GetUnitTestImpl()->PostFlagParsingInit();
+}
+
+}  // namespace internal
+
+// Initializes Google Test.  This must be called before calling
+// RUN_ALL_TESTS().  In particular, it parses a command line for the
+// flags that Google Test recognizes.  Whenever a Google Test flag is
+// seen, it is removed from argv, and *argc is decremented.
+//
+// No value is returned.  Instead, the Google Test flag variables are
+// updated.
+//
+// Calling the function for the second time has no user-visible effect.
+void InitGoogleTest(int* argc, char** argv) {
+  internal::InitGoogleTestImpl(argc, argv);
+}
+
+// This overloaded version can be used in Windows programs compiled in
+// UNICODE mode.
+void InitGoogleTest(int* argc, wchar_t** argv) {
+  internal::InitGoogleTestImpl(argc, argv);
+}
+
+}  // namespace testing
diff --git a/src/LLVM/utils/unittest/googletest/include/gtest/gtest-death-test.h b/src/LLVM/utils/unittest/googletest/include/gtest/gtest-death-test.h
new file mode 100644
index 0000000..121dc1f
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/include/gtest/gtest-death-test.h
@@ -0,0 +1,283 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file defines the public API for death tests.  It is
+// #included by gtest.h so a user doesn't need to include this
+// directly.
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
+#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
+
+#include <gtest/internal/gtest-death-test-internal.h>
+
+namespace testing {
+
+// This flag controls the style of death tests.  Valid values are "threadsafe",
+// meaning that the death test child process will re-execute the test binary
+// from the start, running only a single death test, or "fast",
+// meaning that the child process will execute the test logic immediately
+// after forking.
+GTEST_DECLARE_string_(death_test_style);
+
+#if GTEST_HAS_DEATH_TEST
+
+// The following macros are useful for writing death tests.
+
+// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is
+// executed:
+//
+//   1. It generates a warning if there is more than one active
+//   thread.  This is because it's safe to fork() or clone() only
+//   when there is a single thread.
+//
+//   2. The parent process clone()s a sub-process and runs the death
+//   test in it; the sub-process exits with code 0 at the end of the
+//   death test, if it hasn't exited already.
+//
+//   3. The parent process waits for the sub-process to terminate.
+//
+//   4. The parent process checks the exit code and error message of
+//   the sub-process.
+//
+// Examples:
+//
+//   ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number");
+//   for (int i = 0; i < 5; i++) {
+//     EXPECT_DEATH(server.ProcessRequest(i),
+//                  "Invalid request .* in ProcessRequest()")
+//         << "Failed to die on request " << i);
+//   }
+//
+//   ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting");
+//
+//   bool KilledBySIGHUP(int exit_code) {
+//     return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP;
+//   }
+//
+//   ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!");
+//
+// On the regular expressions used in death tests:
+//
+//   On POSIX-compliant systems (*nix), we use the <regex.h> library,
+//   which uses the POSIX extended regex syntax.
+//
+//   On other platforms (e.g. Windows), we only support a simple regex
+//   syntax implemented as part of Google Test.  This limited
+//   implementation should be enough most of the time when writing
+//   death tests; though it lacks many features you can find in PCRE
+//   or POSIX extended regex syntax.  For example, we don't support
+//   union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and
+//   repetition count ("x{5,7}"), among others.
+//
+//   Below is the syntax that we do support.  We chose it to be a
+//   subset of both PCRE and POSIX extended regex, so it's easy to
+//   learn wherever you come from.  In the following: 'A' denotes a
+//   literal character, period (.), or a single \\ escape sequence;
+//   'x' and 'y' denote regular expressions; 'm' and 'n' are for
+//   natural numbers.
+//
+//     c     matches any literal character c
+//     \\d   matches any decimal digit
+//     \\D   matches any character that's not a decimal digit
+//     \\f   matches \f
+//     \\n   matches \n
+//     \\r   matches \r
+//     \\s   matches any ASCII whitespace, including \n
+//     \\S   matches any character that's not a whitespace
+//     \\t   matches \t
+//     \\v   matches \v
+//     \\w   matches any letter, _, or decimal digit
+//     \\W   matches any character that \\w doesn't match
+//     \\c   matches any literal character c, which must be a punctuation
+//     .     matches any single character except \n
+//     A?    matches 0 or 1 occurrences of A
+//     A*    matches 0 or many occurrences of A
+//     A+    matches 1 or many occurrences of A
+//     ^     matches the beginning of a string (not that of each line)
+//     $     matches the end of a string (not that of each line)
+//     xy    matches x followed by y
+//
+//   If you accidentally use PCRE or POSIX extended regex features
+//   not implemented by us, you will get a run-time failure.  In that
+//   case, please try to rewrite your regular expression within the
+//   above syntax.
+//
+//   This implementation is *not* meant to be as highly tuned or robust
+//   as a compiled regex library, but should perform well enough for a
+//   death test, which already incurs significant overhead by launching
+//   a child process.
+//
+// Known caveats:
+//
+//   A "threadsafe" style death test obtains the path to the test
+//   program from argv[0] and re-executes it in the sub-process.  For
+//   simplicity, the current implementation doesn't search the PATH
+//   when launching the sub-process.  This means that the user must
+//   invoke the test program via a path that contains at least one
+//   path separator (e.g. path/to/foo_test and
+//   /absolute/path/to/bar_test are fine, but foo_test is not).  This
+//   is rarely a problem as people usually don't put the test binary
+//   directory in PATH.
+//
+// TODO(wan@google.com): make thread-safe death tests search the PATH.
+
+// Asserts that a given statement causes the program to exit, with an
+// integer exit status that satisfies predicate, and emitting error output
+// that matches regex.
+#define ASSERT_EXIT(statement, predicate, regex) \
+  GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_)
+
+// Like ASSERT_EXIT, but continues on to successive tests in the
+// test case, if any:
+#define EXPECT_EXIT(statement, predicate, regex) \
+  GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_)
+
+// Asserts that a given statement causes the program to exit, either by
+// explicitly exiting with a nonzero exit code or being killed by a
+// signal, and emitting error output that matches regex.
+#define ASSERT_DEATH(statement, regex) \
+  ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
+
+// Like ASSERT_DEATH, but continues on to successive tests in the
+// test case, if any:
+#define EXPECT_DEATH(statement, regex) \
+  EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
+
+// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
+
+// Tests that an exit code describes a normal exit with a given exit code.
+class GTEST_API_ ExitedWithCode {
+ public:
+  explicit ExitedWithCode(int exit_code);
+  bool operator()(int exit_status) const;
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ExitedWithCode& other);
+
+  const int exit_code_;
+};
+
+#if !GTEST_OS_WINDOWS
+// Tests that an exit code describes an exit due to termination by a
+// given signal.
+class GTEST_API_ KilledBySignal {
+ public:
+  explicit KilledBySignal(int signum);
+  bool operator()(int exit_status) const;
+ private:
+  const int signum_;
+};
+#endif  // !GTEST_OS_WINDOWS
+
+// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.
+// The death testing framework causes this to have interesting semantics,
+// since the sideeffects of the call are only visible in opt mode, and not
+// in debug mode.
+//
+// In practice, this can be used to test functions that utilize the
+// LOG(DFATAL) macro using the following style:
+//
+// int DieInDebugOr12(int* sideeffect) {
+//   if (sideeffect) {
+//     *sideeffect = 12;
+//   }
+//   LOG(DFATAL) << "death";
+//   return 12;
+// }
+//
+// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) {
+//   int sideeffect = 0;
+//   // Only asserts in dbg.
+//   EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death");
+//
+// #ifdef NDEBUG
+//   // opt-mode has sideeffect visible.
+//   EXPECT_EQ(12, sideeffect);
+// #else
+//   // dbg-mode no visible sideeffect.
+//   EXPECT_EQ(0, sideeffect);
+// #endif
+// }
+//
+// This will assert that DieInDebugReturn12InOpt() crashes in debug
+// mode, usually due to a DCHECK or LOG(DFATAL), but returns the
+// appropriate fallback value (12 in this case) in opt mode. If you
+// need to test that a function has appropriate side-effects in opt
+// mode, include assertions against the side-effects.  A general
+// pattern for this is:
+//
+// EXPECT_DEBUG_DEATH({
+//   // Side-effects here will have an effect after this statement in
+//   // opt mode, but none in debug mode.
+//   EXPECT_EQ(12, DieInDebugOr12(&sideeffect));
+// }, "death");
+//
+#ifdef NDEBUG
+
+#define EXPECT_DEBUG_DEATH(statement, regex) \
+  do { statement; } while (::testing::internal::AlwaysFalse())
+
+#define ASSERT_DEBUG_DEATH(statement, regex) \
+  do { statement; } while (::testing::internal::AlwaysFalse())
+
+#else
+
+#define EXPECT_DEBUG_DEATH(statement, regex) \
+  EXPECT_DEATH(statement, regex)
+
+#define ASSERT_DEBUG_DEATH(statement, regex) \
+  ASSERT_DEATH(statement, regex)
+
+#endif  // NDEBUG for EXPECT_DEBUG_DEATH
+#endif  // GTEST_HAS_DEATH_TEST
+
+// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
+// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
+// death tests are supported; otherwise they just issue a warning.  This is
+// useful when you are combining death test assertions with normal test
+// assertions in one test.
+#if GTEST_HAS_DEATH_TEST
+#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
+    EXPECT_DEATH(statement, regex)
+#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
+    ASSERT_DEATH(statement, regex)
+#else
+#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
+    GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, )
+#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
+    GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return)
+#endif
+
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
diff --git a/src/LLVM/utils/unittest/googletest/include/gtest/gtest-message.h b/src/LLVM/utils/unittest/googletest/include/gtest/gtest-message.h
new file mode 100644
index 0000000..f135b69
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/include/gtest/gtest-message.h
@@ -0,0 +1,230 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file defines the Message class.
+//
+// IMPORTANT NOTE: Due to limitation of the C++ language, we have to
+// leave some internal implementation details in this header file.
+// They are clearly marked by comments like this:
+//
+//   // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+//
+// Such code is NOT meant to be used by a user directly, and is subject
+// to CHANGE WITHOUT NOTICE.  Therefore DO NOT DEPEND ON IT in a user
+// program!
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
+#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
+
+#include <limits>
+
+#include <gtest/internal/gtest-string.h>
+#include <gtest/internal/gtest-internal.h>
+
+namespace testing {
+
+// The Message class works like an ostream repeater.
+//
+// Typical usage:
+//
+//   1. You stream a bunch of values to a Message object.
+//      It will remember the text in a StrStream.
+//   2. Then you stream the Message object to an ostream.
+//      This causes the text in the Message to be streamed
+//      to the ostream.
+//
+// For example;
+//
+//   testing::Message foo;
+//   foo << 1 << " != " << 2;
+//   std::cout << foo;
+//
+// will print "1 != 2".
+//
+// Message is not intended to be inherited from.  In particular, its
+// destructor is not virtual.
+//
+// Note that StrStream behaves differently in gcc and in MSVC.  You
+// can stream a NULL char pointer to it in the former, but not in the
+// latter (it causes an access violation if you do).  The Message
+// class hides this difference by treating a NULL char pointer as
+// "(null)".
+class GTEST_API_ Message {
+ private:
+  // The type of basic IO manipulators (endl, ends, and flush) for
+  // narrow streams.
+  typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&);
+
+ public:
+  // Constructs an empty Message.
+  // We allocate the StrStream separately because it otherwise each use of
+  // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's
+  // stack frame leading to huge stack frames in some cases; gcc does not reuse
+  // the stack space.
+  Message() : ss_(new internal::StrStream) {
+    // By default, we want there to be enough precision when printing
+    // a double to a Message.
+    *ss_ << std::setprecision(std::numeric_limits<double>::digits10 + 2);
+  }
+
+  // Copy constructor.
+  Message(const Message& msg) : ss_(new internal::StrStream) {  // NOLINT
+    *ss_ << msg.GetString();
+  }
+
+  // Constructs a Message from a C-string.
+  explicit Message(const char* str) : ss_(new internal::StrStream) {
+    *ss_ << str;
+  }
+
+  ~Message() { delete ss_; }
+#if GTEST_OS_SYMBIAN
+  // Streams a value (either a pointer or not) to this object.
+  template <typename T>
+  inline Message& operator <<(const T& value) {
+    StreamHelper(typename internal::is_pointer<T>::type(), value);
+    return *this;
+  }
+#else
+  // Streams a non-pointer value to this object.
+  template <typename T>
+  inline Message& operator <<(const T& val) {
+    ::GTestStreamToHelper(ss_, val);
+    return *this;
+  }
+
+  // Streams a pointer value to this object.
+  //
+  // This function is an overload of the previous one.  When you
+  // stream a pointer to a Message, this definition will be used as it
+  // is more specialized.  (The C++ Standard, section
+  // [temp.func.order].)  If you stream a non-pointer, then the
+  // previous definition will be used.
+  //
+  // The reason for this overload is that streaming a NULL pointer to
+  // ostream is undefined behavior.  Depending on the compiler, you
+  // may get "0", "(nil)", "(null)", or an access violation.  To
+  // ensure consistent result across compilers, we always treat NULL
+  // as "(null)".
+  template <typename T>
+  inline Message& operator <<(T* const& pointer) {  // NOLINT
+    if (pointer == NULL) {
+      *ss_ << "(null)";
+    } else {
+      ::GTestStreamToHelper(ss_, pointer);
+    }
+    return *this;
+  }
+#endif  // GTEST_OS_SYMBIAN
+
+  // Since the basic IO manipulators are overloaded for both narrow
+  // and wide streams, we have to provide this specialized definition
+  // of operator <<, even though its body is the same as the
+  // templatized version above.  Without this definition, streaming
+  // endl or other basic IO manipulators to Message will confuse the
+  // compiler.
+  Message& operator <<(BasicNarrowIoManip val) {
+    *ss_ << val;
+    return *this;
+  }
+
+  // Instead of 1/0, we want to see true/false for bool values.
+  Message& operator <<(bool b) {
+    return *this << (b ? "true" : "false");
+  }
+
+  // These two overloads allow streaming a wide C string to a Message
+  // using the UTF-8 encoding.
+  Message& operator <<(const wchar_t* wide_c_str) {
+    return *this << internal::String::ShowWideCString(wide_c_str);
+  }
+  Message& operator <<(wchar_t* wide_c_str) {
+    return *this << internal::String::ShowWideCString(wide_c_str);
+  }
+
+#if GTEST_HAS_STD_WSTRING
+  // Converts the given wide string to a narrow string using the UTF-8
+  // encoding, and streams the result to this Message object.
+  Message& operator <<(const ::std::wstring& wstr);
+#endif  // GTEST_HAS_STD_WSTRING
+
+#if GTEST_HAS_GLOBAL_WSTRING
+  // Converts the given wide string to a narrow string using the UTF-8
+  // encoding, and streams the result to this Message object.
+  Message& operator <<(const ::wstring& wstr);
+#endif  // GTEST_HAS_GLOBAL_WSTRING
+
+  // Gets the text streamed to this object so far as a String.
+  // Each '\0' character in the buffer is replaced with "\\0".
+  //
+  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+  internal::String GetString() const {
+    return internal::StrStreamToString(ss_);
+  }
+
+ private:
+#if GTEST_OS_SYMBIAN
+  // These are needed as the Nokia Symbian Compiler cannot decide between
+  // const T& and const T* in a function template. The Nokia compiler _can_
+  // decide between class template specializations for T and T*, so a
+  // tr1::type_traits-like is_pointer works, and we can overload on that.
+  template <typename T>
+  inline void StreamHelper(internal::true_type /*dummy*/, T* pointer) {
+    if (pointer == NULL) {
+      *ss_ << "(null)";
+    } else {
+      ::GTestStreamToHelper(ss_, pointer);
+    }
+  }
+  template <typename T>
+  inline void StreamHelper(internal::false_type /*dummy*/, const T& value) {
+    ::GTestStreamToHelper(ss_, value);
+  }
+#endif  // GTEST_OS_SYMBIAN
+
+  // We'll hold the text streamed to this object here.
+  internal::StrStream* const ss_;
+
+  // We declare (but don't implement) this to prevent the compiler
+  // from implementing the assignment operator.
+  void operator=(const Message&);
+};
+
+// Streams a Message to an ostream.
+inline std::ostream& operator <<(std::ostream& os, const Message& sb) {
+  return os << sb.GetString();
+}
+
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
diff --git a/src/LLVM/utils/unittest/googletest/include/gtest/gtest-param-test.h b/src/LLVM/utils/unittest/googletest/include/gtest/gtest-param-test.h
new file mode 100644
index 0000000..3184d07
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/include/gtest/gtest-param-test.h
@@ -0,0 +1,1397 @@
+// This file was GENERATED by a script.  DO NOT EDIT BY HAND!!!
+
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: vladl@google.com (Vlad Losev)
+//
+// Macros and functions for implementing parameterized tests
+// in Google C++ Testing Framework (Google Test)
+//
+// This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!
+//
+#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
+#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
+
+
+// Value-parameterized tests allow you to test your code with different
+// parameters without writing multiple copies of the same test.
+//
+// Here is how you use value-parameterized tests:
+
+#if 0
+
+// To write value-parameterized tests, first you should define a fixture
+// class. It must be derived from testing::TestWithParam<T>, where T is
+// the type of your parameter values. TestWithParam<T> is itself derived
+// from testing::Test. T can be any copyable type. If it's a raw pointer,
+// you are responsible for managing the lifespan of the pointed values.
+
+class FooTest : public ::testing::TestWithParam<const char*> {
+  // You can implement all the usual class fixture members here.
+};
+
+// Then, use the TEST_P macro to define as many parameterized tests
+// for this fixture as you want. The _P suffix is for "parameterized"
+// or "pattern", whichever you prefer to think.
+
+TEST_P(FooTest, DoesBlah) {
+  // Inside a test, access the test parameter with the GetParam() method
+  // of the TestWithParam<T> class:
+  EXPECT_TRUE(foo.Blah(GetParam()));
+  ...
+}
+
+TEST_P(FooTest, HasBlahBlah) {
+  ...
+}
+
+// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test
+// case with any set of parameters you want. Google Test defines a number
+// of functions for generating test parameters. They return what we call
+// (surprise!) parameter generators. Here is a  summary of them, which
+// are all in the testing namespace:
+//
+//
+//  Range(begin, end [, step]) - Yields values {begin, begin+step,
+//                               begin+step+step, ...}. The values do not
+//                               include end. step defaults to 1.
+//  Values(v1, v2, ..., vN)    - Yields values {v1, v2, ..., vN}.
+//  ValuesIn(container)        - Yields values from a C-style array, an STL
+//  ValuesIn(begin,end)          container, or an iterator range [begin, end).
+//  Bool()                     - Yields sequence {false, true}.
+//  Combine(g1, g2, ..., gN)   - Yields all combinations (the Cartesian product
+//                               for the math savvy) of the values generated
+//                               by the N generators.
+//
+// For more details, see comments at the definitions of these functions below
+// in this file.
+//
+// The following statement will instantiate tests from the FooTest test case
+// each with parameter values "meeny", "miny", and "moe".
+
+INSTANTIATE_TEST_CASE_P(InstantiationName,
+                        FooTest,
+                        Values("meeny", "miny", "moe"));
+
+// To distinguish different instances of the pattern, (yes, you
+// can instantiate it more then once) the first argument to the
+// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the
+// actual test case name. Remember to pick unique prefixes for different
+// instantiations. The tests from the instantiation above will have
+// these names:
+//
+//    * InstantiationName/FooTest.DoesBlah/0 for "meeny"
+//    * InstantiationName/FooTest.DoesBlah/1 for "miny"
+//    * InstantiationName/FooTest.DoesBlah/2 for "moe"
+//    * InstantiationName/FooTest.HasBlahBlah/0 for "meeny"
+//    * InstantiationName/FooTest.HasBlahBlah/1 for "miny"
+//    * InstantiationName/FooTest.HasBlahBlah/2 for "moe"
+//
+// You can use these names in --gtest_filter.
+//
+// This statement will instantiate all tests from FooTest again, each
+// with parameter values "cat" and "dog":
+
+const char* pets[] = {"cat", "dog"};
+INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
+
+// The tests from the instantiation above will have these names:
+//
+//    * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
+//    * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
+//    * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
+//    * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
+//
+// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests
+// in the given test case, whether their definitions come before or
+// AFTER the INSTANTIATE_TEST_CASE_P statement.
+//
+// Please also note that generator expressions (including parameters to the
+// generators) are evaluated in InitGoogleTest(), after main() has started.
+// This allows the user on one hand, to adjust generator parameters in order
+// to dynamically determine a set of tests to run and on the other hand,
+// give the user a chance to inspect the generated tests with Google Test
+// reflection API before RUN_ALL_TESTS() is executed.
+//
+// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
+// for more examples.
+//
+// In the future, we plan to publish the API for defining new parameter
+// generators. But for now this interface remains part of the internal
+// implementation and is subject to change.
+
+#endif  // 0
+
+#include <gtest/internal/gtest-port.h>
+
+#if !GTEST_OS_SYMBIAN
+#include <utility>
+#endif
+
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*.  Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
+#include <gtest/internal/gtest-internal.h>
+#include <gtest/internal/gtest-param-util.h>
+
+#if GTEST_HAS_PARAM_TEST
+
+namespace testing {
+
+// Functions producing parameter generators.
+//
+// Google Test uses these generators to produce parameters for value-
+// parameterized tests. When a parameterized test case is instantiated
+// with a particular generator, Google Test creates and runs tests
+// for each element in the sequence produced by the generator.
+//
+// In the following sample, tests from test case FooTest are instantiated
+// each three times with parameter values 3, 5, and 8:
+//
+// class FooTest : public TestWithParam<int> { ... };
+//
+// TEST_P(FooTest, TestThis) {
+// }
+// TEST_P(FooTest, TestThat) {
+// }
+// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8));
+//
+
+// Range() returns generators providing sequences of values in a range.
+//
+// Synopsis:
+// Range(start, end)
+//   - returns a generator producing a sequence of values {start, start+1,
+//     start+2, ..., }.
+// Range(start, end, step)
+//   - returns a generator producing a sequence of values {start, start+step,
+//     start+step+step, ..., }.
+// Notes:
+//   * The generated sequences never include end. For example, Range(1, 5)
+//     returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)
+//     returns a generator producing {1, 3, 5, 7}.
+//   * start and end must have the same type. That type may be any integral or
+//     floating-point type or a user defined type satisfying these conditions:
+//     * It must be assignable (have operator=() defined).
+//     * It must have operator+() (operator+(int-compatible type) for
+//       two-operand version).
+//     * It must have operator<() defined.
+//     Elements in the resulting sequences will also have that type.
+//   * Condition start < end must be satisfied in order for resulting sequences
+//     to contain any elements.
+//
+template <typename T, typename IncrementT>
+internal::ParamGenerator<T> Range(T start, T end, IncrementT step) {
+  return internal::ParamGenerator<T>(
+      new internal::RangeGenerator<T, IncrementT>(start, end, step));
+}
+
+template <typename T>
+internal::ParamGenerator<T> Range(T start, T end) {
+  return Range(start, end, 1);
+}
+
+// ValuesIn() function allows generation of tests with parameters coming from
+// a container.
+//
+// Synopsis:
+// ValuesIn(const T (&array)[N])
+//   - returns a generator producing sequences with elements from
+//     a C-style array.
+// ValuesIn(const Container& container)
+//   - returns a generator producing sequences with elements from
+//     an STL-style container.
+// ValuesIn(Iterator begin, Iterator end)
+//   - returns a generator producing sequences with elements from
+//     a range [begin, end) defined by a pair of STL-style iterators. These
+//     iterators can also be plain C pointers.
+//
+// Please note that ValuesIn copies the values from the containers
+// passed in and keeps them to generate tests in RUN_ALL_TESTS().
+//
+// Examples:
+//
+// This instantiates tests from test case StringTest
+// each with C-string values of "foo", "bar", and "baz":
+//
+// const char* strings[] = {"foo", "bar", "baz"};
+// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings));
+//
+// This instantiates tests from test case StlStringTest
+// each with STL strings with values "a" and "b":
+//
+// ::std::vector< ::std::string> GetParameterStrings() {
+//   ::std::vector< ::std::string> v;
+//   v.push_back("a");
+//   v.push_back("b");
+//   return v;
+// }
+//
+// INSTANTIATE_TEST_CASE_P(CharSequence,
+//                         StlStringTest,
+//                         ValuesIn(GetParameterStrings()));
+//
+//
+// This will also instantiate tests from CharTest
+// each with parameter values 'a' and 'b':
+//
+// ::std::list<char> GetParameterChars() {
+//   ::std::list<char> list;
+//   list.push_back('a');
+//   list.push_back('b');
+//   return list;
+// }
+// ::std::list<char> l = GetParameterChars();
+// INSTANTIATE_TEST_CASE_P(CharSequence2,
+//                         CharTest,
+//                         ValuesIn(l.begin(), l.end()));
+//
+template <typename ForwardIterator>
+internal::ParamGenerator<
+    typename ::std::iterator_traits<ForwardIterator>::value_type> ValuesIn(
+  ForwardIterator begin,
+  ForwardIterator end) {
+  typedef typename ::std::iterator_traits<ForwardIterator>::value_type
+      ParamType;
+  return internal::ParamGenerator<ParamType>(
+      new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));
+}
+
+template <typename T, size_t N>
+internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {
+  return ValuesIn(array, array + N);
+}
+
+template <class Container>
+internal::ParamGenerator<typename Container::value_type> ValuesIn(
+    const Container& container) {
+  return ValuesIn(container.begin(), container.end());
+}
+
+} // namespace testing
+
+#include <gtest/internal/gtest-param-util-generated.h>
+
+namespace testing {
+
+// Values() allows generating tests from explicitly specified list of
+// parameters.
+//
+// Synopsis:
+// Values(T v1, T v2, ..., T vN)
+//   - returns a generator producing sequences with elements v1, v2, ..., vN.
+//
+// For example, this instantiates tests from test case BarTest each
+// with values "one", "two", and "three":
+//
+// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three"));
+//
+// This instantiates tests from test case BazTest each with values 1, 2, 3.5.
+// The exact type of values will depend on the type of parameter in BazTest.
+//
+// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
+//
+// Currently, Values() supports from 1 to 50 parameters.
+//
+template <typename T1>
+internal::ValueArray1<T1> Values(T1 v1) {
+  return internal::ValueArray1<T1>(v1);
+}
+
+template <typename T1, typename T2>
+internal::ValueArray2<T1, T2> Values(T1 v1, T2 v2) {
+  return internal::ValueArray2<T1, T2>(v1, v2);
+}
+
+template <typename T1, typename T2, typename T3>
+internal::ValueArray3<T1, T2, T3> Values(T1 v1, T2 v2, T3 v3) {
+  return internal::ValueArray3<T1, T2, T3>(v1, v2, v3);
+}
+
+template <typename T1, typename T2, typename T3, typename T4>
+internal::ValueArray4<T1, T2, T3, T4> Values(T1 v1, T2 v2, T3 v3, T4 v4) {
+  return internal::ValueArray4<T1, T2, T3, T4>(v1, v2, v3, v4);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+internal::ValueArray5<T1, T2, T3, T4, T5> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5) {
+  return internal::ValueArray5<T1, T2, T3, T4, T5>(v1, v2, v3, v4, v5);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6>
+internal::ValueArray6<T1, T2, T3, T4, T5, T6> Values(T1 v1, T2 v2, T3 v3,
+    T4 v4, T5 v5, T6 v6) {
+  return internal::ValueArray6<T1, T2, T3, T4, T5, T6>(v1, v2, v3, v4, v5, v6);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7>
+internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7> Values(T1 v1, T2 v2, T3 v3,
+    T4 v4, T5 v5, T6 v6, T7 v7) {
+  return internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7>(v1, v2, v3, v4, v5,
+      v6, v7);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8>
+internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+  return internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8>(v1, v2, v3, v4,
+      v5, v6, v7, v8);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9>
+internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+  return internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(v1, v2, v3,
+      v4, v5, v6, v7, v8, v9);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10>
+internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Values(T1 v1,
+    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+  return internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(v1,
+      v2, v3, v4, v5, v6, v7, v8, v9, v10);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11>
+internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
+    T11> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11) {
+  return internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
+      T11>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12>
+internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+    T12> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12) {
+  return internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13>
+internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+    T13> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13) {
+  return internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14>
+internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) {
+  return internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
+      v14);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15>
+internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
+    T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) {
+  return internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
+      v13, v14, v15);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16>
+internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16) {
+  return internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
+      v12, v13, v14, v15, v16);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17>
+internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17) {
+  return internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
+      v11, v12, v13, v14, v15, v16, v17);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18>
+internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
+    T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18) {
+  return internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
+      v10, v11, v12, v13, v14, v15, v16, v17, v18);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19>
+internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
+    T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
+    T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) {
+  return internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19>(v1, v2, v3, v4, v5, v6, v7, v8,
+      v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20>
+internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) {
+  return internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20>(v1, v2, v3, v4, v5, v6, v7,
+      v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21>
+internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) {
+  return internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(v1, v2, v3, v4, v5, v6,
+      v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22>
+internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22> Values(T1 v1, T2 v2, T3 v3,
+    T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22) {
+  return internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22>(v1, v2, v3, v4,
+      v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+      v20, v21, v22);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23>
+internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22, T23 v23) {
+  return internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23>(v1, v2, v3,
+      v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+      v20, v21, v22, v23);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24>
+internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22, T23 v23, T24 v24) {
+  return internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24>(v1, v2,
+      v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18,
+      v19, v20, v21, v22, v23, v24);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25>
+internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Values(T1 v1,
+    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11,
+    T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19,
+    T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) {
+  return internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25>(v1,
+      v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17,
+      v18, v19, v20, v21, v22, v23, v24, v25);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26>
+internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+    T26> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26) {
+  return internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
+      v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27>
+internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+    T27> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27) {
+  return internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14,
+      v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28>
+internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+    T28> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28) {
+  return internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
+      v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27,
+      v28);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29>
+internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28, T29 v29) {
+  return internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
+      v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26,
+      v27, v28, v29);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30>
+internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
+    T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
+    T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
+    T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) {
+  return internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
+      v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25,
+      v26, v27, v28, v29, v30);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31>
+internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) {
+  return internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
+      v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24,
+      v25, v26, v27, v28, v29, v30, v31);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32>
+internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+    T32 v32) {
+  return internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
+      v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
+      v24, v25, v26, v27, v28, v29, v30, v31, v32);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33>
+internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
+    T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+    T32 v32, T33 v33) {
+  return internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33>(v1, v2, v3, v4, v5, v6, v7, v8,
+      v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
+      v24, v25, v26, v27, v28, v29, v30, v31, v32, v33);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34>
+internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
+    T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
+    T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22,
+    T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30,
+    T31 v31, T32 v32, T33 v33, T34 v34) {
+  return internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34>(v1, v2, v3, v4, v5, v6, v7,
+      v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22,
+      v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35>
+internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
+    T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
+    T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) {
+  return internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35>(v1, v2, v3, v4, v5, v6,
+      v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21,
+      v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36>
+internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
+    T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
+    T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) {
+  return internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36>(v1, v2, v3, v4,
+      v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+      v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
+      v34, v35, v36);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37>
+internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37> Values(T1 v1, T2 v2, T3 v3,
+    T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
+    T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
+    T37 v37) {
+  return internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37>(v1, v2, v3,
+      v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+      v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
+      v34, v35, v36, v37);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38>
+internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
+    T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
+    T37 v37, T38 v38) {
+  return internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38>(v1, v2,
+      v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18,
+      v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32,
+      v33, v34, v35, v36, v37, v38);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39>
+internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
+    T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
+    T37 v37, T38 v38, T39 v39) {
+  return internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39>(v1,
+      v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17,
+      v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31,
+      v32, v33, v34, v35, v36, v37, v38, v39);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40>
+internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Values(T1 v1,
+    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11,
+    T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19,
+    T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27,
+    T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35,
+    T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) {
+  return internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
+      v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29,
+      v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41>
+internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+    T41> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) {
+  return internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14,
+      v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28,
+      v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42>
+internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+    T42> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+    T42 v42) {
+  return internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
+      v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27,
+      v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41,
+      v42);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43>
+internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+    T43> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+    T42 v42, T43 v43) {
+  return internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
+      v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26,
+      v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40,
+      v41, v42, v43);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44>
+internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+    T42 v42, T43 v43, T44 v44) {
+  return internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
+      v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25,
+      v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39,
+      v40, v41, v42, v43, v44);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45>
+internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
+    T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
+    T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
+    T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32,
+    T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40,
+    T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) {
+  return internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
+      v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24,
+      v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38,
+      v39, v40, v41, v42, v43, v44, v45);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46>
+internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
+    T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) {
+  return internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45, T46>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
+      v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
+      v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37,
+      v38, v39, v40, v41, v42, v43, v44, v45, v46);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47>
+internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46, T47> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
+    T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) {
+  return internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45, T46, T47>(v1, v2, v3, v4, v5, v6, v7, v8,
+      v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
+      v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37,
+      v38, v39, v40, v41, v42, v43, v44, v45, v46, v47);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48>
+internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46, T47, T48> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
+    T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
+    T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47,
+    T48 v48) {
+  return internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45, T46, T47, T48>(v1, v2, v3, v4, v5, v6, v7,
+      v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22,
+      v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36,
+      v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49>
+internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46, T47, T48, T49> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
+    T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
+    T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22,
+    T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30,
+    T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38,
+    T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46,
+    T47 v47, T48 v48, T49 v49) {
+  return internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45, T46, T47, T48, T49>(v1, v2, v3, v4, v5, v6,
+      v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21,
+      v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35,
+      v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49, typename T50>
+internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46, T47, T48, T49, T50> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
+    T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
+    T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37,
+    T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45,
+    T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) {
+  return internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>(v1, v2, v3, v4,
+      v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+      v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
+      v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47,
+      v48, v49, v50);
+}
+
+// Bool() allows generating tests with parameters in a set of (false, true).
+//
+// Synopsis:
+// Bool()
+//   - returns a generator producing sequences with elements {false, true}.
+//
+// It is useful when testing code that depends on Boolean flags. Combinations
+// of multiple flags can be tested when several Bool()'s are combined using
+// Combine() function.
+//
+// In the following example all tests in the test case FlagDependentTest
+// will be instantiated twice with parameters false and true.
+//
+// class FlagDependentTest : public testing::TestWithParam<bool> {
+//   virtual void SetUp() {
+//     external_flag = GetParam();
+//   }
+// }
+// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool());
+//
+inline internal::ParamGenerator<bool> Bool() {
+  return Values(false, true);
+}
+
+#if GTEST_HAS_COMBINE
+// Combine() allows the user to combine two or more sequences to produce
+// values of a Cartesian product of those sequences' elements.
+//
+// Synopsis:
+// Combine(gen1, gen2, ..., genN)
+//   - returns a generator producing sequences with elements coming from
+//     the Cartesian product of elements from the sequences generated by
+//     gen1, gen2, ..., genN. The sequence elements will have a type of
+//     tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
+//     of elements from sequences produces by gen1, gen2, ..., genN.
+//
+// Combine can have up to 10 arguments. This number is currently limited
+// by the maximum number of elements in the tuple implementation used by Google
+// Test.
+//
+// Example:
+//
+// This will instantiate tests in test case AnimalTest each one with
+// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
+// tuple("dog", BLACK), and tuple("dog", WHITE):
+//
+// enum Color { BLACK, GRAY, WHITE };
+// class AnimalTest
+//     : public testing::TestWithParam<tuple<const char*, Color> > {...};
+//
+// TEST_P(AnimalTest, AnimalLooksNice) {...}
+//
+// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest,
+//                         Combine(Values("cat", "dog"),
+//                                 Values(BLACK, WHITE)));
+//
+// This will instantiate tests in FlagDependentTest with all variations of two
+// Boolean flags:
+//
+// class FlagDependentTest
+//     : public testing::TestWithParam<tuple(bool, bool)> > {
+//   virtual void SetUp() {
+//     // Assigns external_flag_1 and external_flag_2 values from the tuple.
+//     tie(external_flag_1, external_flag_2) = GetParam();
+//   }
+// };
+//
+// TEST_P(FlagDependentTest, TestFeature1) {
+//   // Test your code using external_flag_1 and external_flag_2 here.
+// }
+// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest,
+//                         Combine(Bool(), Bool()));
+//
+template <typename Generator1, typename Generator2>
+internal::CartesianProductHolder2<Generator1, Generator2> Combine(
+    const Generator1& g1, const Generator2& g2) {
+  return internal::CartesianProductHolder2<Generator1, Generator2>(
+      g1, g2);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3>
+internal::CartesianProductHolder3<Generator1, Generator2, Generator3> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3) {
+  return internal::CartesianProductHolder3<Generator1, Generator2, Generator3>(
+      g1, g2, g3);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4>
+internal::CartesianProductHolder4<Generator1, Generator2, Generator3,
+    Generator4> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4) {
+  return internal::CartesianProductHolder4<Generator1, Generator2, Generator3,
+      Generator4>(
+      g1, g2, g3, g4);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5>
+internal::CartesianProductHolder5<Generator1, Generator2, Generator3,
+    Generator4, Generator5> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5) {
+  return internal::CartesianProductHolder5<Generator1, Generator2, Generator3,
+      Generator4, Generator5>(
+      g1, g2, g3, g4, g5);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5, typename Generator6>
+internal::CartesianProductHolder6<Generator1, Generator2, Generator3,
+    Generator4, Generator5, Generator6> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5, const Generator6& g6) {
+  return internal::CartesianProductHolder6<Generator1, Generator2, Generator3,
+      Generator4, Generator5, Generator6>(
+      g1, g2, g3, g4, g5, g6);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5, typename Generator6,
+    typename Generator7>
+internal::CartesianProductHolder7<Generator1, Generator2, Generator3,
+    Generator4, Generator5, Generator6, Generator7> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5, const Generator6& g6,
+        const Generator7& g7) {
+  return internal::CartesianProductHolder7<Generator1, Generator2, Generator3,
+      Generator4, Generator5, Generator6, Generator7>(
+      g1, g2, g3, g4, g5, g6, g7);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5, typename Generator6,
+    typename Generator7, typename Generator8>
+internal::CartesianProductHolder8<Generator1, Generator2, Generator3,
+    Generator4, Generator5, Generator6, Generator7, Generator8> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5, const Generator6& g6,
+        const Generator7& g7, const Generator8& g8) {
+  return internal::CartesianProductHolder8<Generator1, Generator2, Generator3,
+      Generator4, Generator5, Generator6, Generator7, Generator8>(
+      g1, g2, g3, g4, g5, g6, g7, g8);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5, typename Generator6,
+    typename Generator7, typename Generator8, typename Generator9>
+internal::CartesianProductHolder9<Generator1, Generator2, Generator3,
+    Generator4, Generator5, Generator6, Generator7, Generator8,
+    Generator9> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5, const Generator6& g6,
+        const Generator7& g7, const Generator8& g8, const Generator9& g9) {
+  return internal::CartesianProductHolder9<Generator1, Generator2, Generator3,
+      Generator4, Generator5, Generator6, Generator7, Generator8, Generator9>(
+      g1, g2, g3, g4, g5, g6, g7, g8, g9);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5, typename Generator6,
+    typename Generator7, typename Generator8, typename Generator9,
+    typename Generator10>
+internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
+    Generator4, Generator5, Generator6, Generator7, Generator8, Generator9,
+    Generator10> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5, const Generator6& g6,
+        const Generator7& g7, const Generator8& g8, const Generator9& g9,
+        const Generator10& g10) {
+  return internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
+      Generator4, Generator5, Generator6, Generator7, Generator8, Generator9,
+      Generator10>(
+      g1, g2, g3, g4, g5, g6, g7, g8, g9, g10);
+}
+#endif  // GTEST_HAS_COMBINE
+
+
+
+#define TEST_P(test_case_name, test_name) \
+  class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
+      : public test_case_name { \
+   public: \
+    GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \
+    virtual void TestBody(); \
+   private: \
+    static int AddToRegistry() { \
+      ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
+          GetTestCasePatternHolder<test_case_name>(\
+              #test_case_name, __FILE__, __LINE__)->AddTestPattern(\
+                  #test_case_name, \
+                  #test_name, \
+                  new ::testing::internal::TestMetaFactory< \
+                      GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \
+      return 0; \
+    } \
+    static int gtest_registering_dummy_; \
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(\
+        GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
+  }; \
+  int GTEST_TEST_CLASS_NAME_(test_case_name, \
+                             test_name)::gtest_registering_dummy_ = \
+      GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
+  void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
+
+#define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
+  ::testing::internal::ParamGenerator<test_case_name::ParamType> \
+      gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
+  int gtest_##prefix##test_case_name##_dummy_ = \
+      ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
+          GetTestCasePatternHolder<test_case_name>(\
+              #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\
+                  #prefix, \
+                  &gtest_##prefix##test_case_name##_EvalGenerator_, \
+                  __FILE__, __LINE__)
+
+}  // namespace testing
+
+#endif  // GTEST_HAS_PARAM_TEST
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
diff --git a/src/LLVM/utils/unittest/googletest/include/gtest/gtest-spi.h b/src/LLVM/utils/unittest/googletest/include/gtest/gtest-spi.h
new file mode 100644
index 0000000..c41da48
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/include/gtest/gtest-spi.h
@@ -0,0 +1,232 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// Utilities for testing Google Test itself and code that uses Google Test
+// (e.g. frameworks built on top of Google Test).
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_
+#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_
+
+#include <gtest/gtest.h>
+
+namespace testing {
+
+// This helper class can be used to mock out Google Test failure reporting
+// so that we can test Google Test or code that builds on Google Test.
+//
+// An object of this class appends a TestPartResult object to the
+// TestPartResultArray object given in the constructor whenever a Google Test
+// failure is reported. It can either intercept only failures that are
+// generated in the same thread that created this object or it can intercept
+// all generated failures. The scope of this mock object can be controlled with
+// the second argument to the two arguments constructor.
+class GTEST_API_ ScopedFakeTestPartResultReporter
+    : public TestPartResultReporterInterface {
+ public:
+  // The two possible mocking modes of this object.
+  enum InterceptMode {
+    INTERCEPT_ONLY_CURRENT_THREAD,  // Intercepts only thread local failures.
+    INTERCEPT_ALL_THREADS           // Intercepts all failures.
+  };
+
+  // The c'tor sets this object as the test part result reporter used
+  // by Google Test.  The 'result' parameter specifies where to report the
+  // results. This reporter will only catch failures generated in the current
+  // thread. DEPRECATED
+  explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);
+
+  // Same as above, but you can choose the interception scope of this object.
+  ScopedFakeTestPartResultReporter(InterceptMode intercept_mode,
+                                   TestPartResultArray* result);
+
+  // The d'tor restores the previous test part result reporter.
+  virtual ~ScopedFakeTestPartResultReporter();
+
+  // Appends the TestPartResult object to the TestPartResultArray
+  // received in the constructor.
+  //
+  // This method is from the TestPartResultReporterInterface
+  // interface.
+  virtual void ReportTestPartResult(const TestPartResult& result);
+ private:
+  void Init();
+
+  const InterceptMode intercept_mode_;
+  TestPartResultReporterInterface* old_reporter_;
+  TestPartResultArray* const result_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter);
+};
+
+namespace internal {
+
+// A helper class for implementing EXPECT_FATAL_FAILURE() and
+// EXPECT_NONFATAL_FAILURE().  Its destructor verifies that the given
+// TestPartResultArray contains exactly one failure that has the given
+// type and contains the given substring.  If that's not the case, a
+// non-fatal failure will be generated.
+class GTEST_API_ SingleFailureChecker {
+ public:
+  // The constructor remembers the arguments.
+  SingleFailureChecker(const TestPartResultArray* results,
+                       TestPartResult::Type type,
+                       const char* substr);
+  ~SingleFailureChecker();
+ private:
+  const TestPartResultArray* const results_;
+  const TestPartResult::Type type_;
+  const String substr_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);
+};
+
+}  // namespace internal
+
+}  // namespace testing
+
+// A set of macros for testing Google Test assertions or code that's expected
+// to generate Google Test fatal failures.  It verifies that the given
+// statement will cause exactly one fatal Google Test failure with 'substr'
+// being part of the failure message.
+//
+// There are two different versions of this macro. EXPECT_FATAL_FAILURE only
+// affects and considers failures generated in the current thread and
+// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
+//
+// The verification of the assertion is done correctly even when the statement
+// throws an exception or aborts the current function.
+//
+// Known restrictions:
+//   - 'statement' cannot reference local non-static variables or
+//     non-static members of the current object.
+//   - 'statement' cannot return a value.
+//   - You cannot stream a failure message to this macro.
+//
+// Note that even though the implementations of the following two
+// macros are much alike, we cannot refactor them to use a common
+// helper macro, due to some peculiarity in how the preprocessor
+// works.  The AcceptsMacroThatExpandsToUnprotectedComma test in
+// gtest_unittest.cc will fail to compile if we do that.
+#define EXPECT_FATAL_FAILURE(statement, substr) \
+  do { \
+    class GTestExpectFatalFailureHelper {\
+     public:\
+      static void Execute() { statement; }\
+    };\
+    ::testing::TestPartResultArray gtest_failures;\
+    ::testing::internal::SingleFailureChecker gtest_checker(\
+        &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
+    {\
+      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+          ::testing::ScopedFakeTestPartResultReporter:: \
+          INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
+      GTestExpectFatalFailureHelper::Execute();\
+    }\
+  } while (::testing::internal::AlwaysFalse())
+
+#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
+  do { \
+    class GTestExpectFatalFailureHelper {\
+     public:\
+      static void Execute() { statement; }\
+    };\
+    ::testing::TestPartResultArray gtest_failures;\
+    ::testing::internal::SingleFailureChecker gtest_checker(\
+        &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
+    {\
+      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+          ::testing::ScopedFakeTestPartResultReporter:: \
+          INTERCEPT_ALL_THREADS, &gtest_failures);\
+      GTestExpectFatalFailureHelper::Execute();\
+    }\
+  } while (::testing::internal::AlwaysFalse())
+
+// A macro for testing Google Test assertions or code that's expected to
+// generate Google Test non-fatal failures.  It asserts that the given
+// statement will cause exactly one non-fatal Google Test failure with 'substr'
+// being part of the failure message.
+//
+// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only
+// affects and considers failures generated in the current thread and
+// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
+//
+// 'statement' is allowed to reference local variables and members of
+// the current object.
+//
+// The verification of the assertion is done correctly even when the statement
+// throws an exception or aborts the current function.
+//
+// Known restrictions:
+//   - You cannot stream a failure message to this macro.
+//
+// Note that even though the implementations of the following two
+// macros are much alike, we cannot refactor them to use a common
+// helper macro, due to some peculiarity in how the preprocessor
+// works.  If we do that, the code won't compile when the user gives
+// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that
+// expands to code containing an unprotected comma.  The
+// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc
+// catches that.
+//
+// For the same reason, we have to write
+//   if (::testing::internal::AlwaysTrue()) { statement; }
+// instead of
+//   GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
+// to avoid an MSVC warning on unreachable code.
+#define EXPECT_NONFATAL_FAILURE(statement, substr) \
+  do {\
+    ::testing::TestPartResultArray gtest_failures;\
+    ::testing::internal::SingleFailureChecker gtest_checker(\
+        &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
+        (substr));\
+    {\
+      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+          ::testing::ScopedFakeTestPartResultReporter:: \
+          INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
+      if (::testing::internal::AlwaysTrue()) { statement; }\
+    }\
+  } while (::testing::internal::AlwaysFalse())
+
+#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
+  do {\
+    ::testing::TestPartResultArray gtest_failures;\
+    ::testing::internal::SingleFailureChecker gtest_checker(\
+        &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
+        (substr));\
+    {\
+      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+          ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS,\
+          &gtest_failures);\
+      if (::testing::internal::AlwaysTrue()) { statement; }\
+    }\
+  } while (::testing::internal::AlwaysFalse())
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_SPI_H_
diff --git a/src/LLVM/utils/unittest/googletest/include/gtest/gtest-test-part.h b/src/LLVM/utils/unittest/googletest/include/gtest/gtest-test-part.h
new file mode 100644
index 0000000..f714759
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/include/gtest/gtest-test-part.h
@@ -0,0 +1,176 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: mheule@google.com (Markus Heule)
+//
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
+#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
+
+#include <iosfwd>
+#include <vector>
+#include <gtest/internal/gtest-internal.h>
+#include <gtest/internal/gtest-string.h>
+
+namespace testing {
+
+// A copyable object representing the result of a test part (i.e. an
+// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).
+//
+// Don't inherit from TestPartResult as its destructor is not virtual.
+class GTEST_API_ TestPartResult {
+ public:
+  // The possible outcomes of a test part (i.e. an assertion or an
+  // explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
+  enum Type {
+    kSuccess,          // Succeeded.
+    kNonFatalFailure,  // Failed but the test can continue.
+    kFatalFailure      // Failed and the test should be terminated.
+  };
+
+  // C'tor.  TestPartResult does NOT have a default constructor.
+  // Always use this constructor (with parameters) to create a
+  // TestPartResult object.
+  TestPartResult(Type a_type,
+                 const char* a_file_name,
+                 int a_line_number,
+                 const char* a_message)
+      : type_(a_type),
+        file_name_(a_file_name),
+        line_number_(a_line_number),
+        summary_(ExtractSummary(a_message)),
+        message_(a_message) {
+  }
+
+  // Gets the outcome of the test part.
+  Type type() const { return type_; }
+
+  // Gets the name of the source file where the test part took place, or
+  // NULL if it's unknown.
+  const char* file_name() const { return file_name_.c_str(); }
+
+  // Gets the line in the source file where the test part took place,
+  // or -1 if it's unknown.
+  int line_number() const { return line_number_; }
+
+  // Gets the summary of the failure message.
+  const char* summary() const { return summary_.c_str(); }
+
+  // Gets the message associated with the test part.
+  const char* message() const { return message_.c_str(); }
+
+  // Returns true iff the test part passed.
+  bool passed() const { return type_ == kSuccess; }
+
+  // Returns true iff the test part failed.
+  bool failed() const { return type_ != kSuccess; }
+
+  // Returns true iff the test part non-fatally failed.
+  bool nonfatally_failed() const { return type_ == kNonFatalFailure; }
+
+  // Returns true iff the test part fatally failed.
+  bool fatally_failed() const { return type_ == kFatalFailure; }
+ private:
+  Type type_;
+
+  // Gets the summary of the failure message by omitting the stack
+  // trace in it.
+  static internal::String ExtractSummary(const char* message);
+
+  // The name of the source file where the test part took place, or
+  // NULL if the source file is unknown.
+  internal::String file_name_;
+  // The line in the source file where the test part took place, or -1
+  // if the line number is unknown.
+  int line_number_;
+  internal::String summary_;  // The test failure summary.
+  internal::String message_;  // The test failure message.
+};
+
+// Prints a TestPartResult object.
+std::ostream& operator<<(std::ostream& os, const TestPartResult& result);
+
+// An array of TestPartResult objects.
+//
+// Don't inherit from TestPartResultArray as its destructor is not
+// virtual.
+class GTEST_API_ TestPartResultArray {
+ public:
+  TestPartResultArray() {}
+
+  // Appends the given TestPartResult to the array.
+  void Append(const TestPartResult& result);
+
+  // Returns the TestPartResult at the given index (0-based).
+  const TestPartResult& GetTestPartResult(int index) const;
+
+  // Returns the number of TestPartResult objects in the array.
+  int size() const;
+
+ private:
+  std::vector<TestPartResult> array_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray);
+};
+
+// This interface knows how to report a test part result.
+class TestPartResultReporterInterface {
+ public:
+  virtual ~TestPartResultReporterInterface() {}
+
+  virtual void ReportTestPartResult(const TestPartResult& result) = 0;
+};
+
+namespace internal {
+
+// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a
+// statement generates new fatal failures. To do so it registers itself as the
+// current test part result reporter. Besides checking if fatal failures were
+// reported, it only delegates the reporting to the former result reporter.
+// The original result reporter is restored in the destructor.
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+class GTEST_API_ HasNewFatalFailureHelper
+    : public TestPartResultReporterInterface {
+ public:
+  HasNewFatalFailureHelper();
+  virtual ~HasNewFatalFailureHelper();
+  virtual void ReportTestPartResult(const TestPartResult& result);
+  bool has_new_fatal_failure() const { return has_new_fatal_failure_; }
+ private:
+  bool has_new_fatal_failure_;
+  TestPartResultReporterInterface* original_reporter_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper);
+};
+
+}  // namespace internal
+
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
diff --git a/src/LLVM/utils/unittest/googletest/include/gtest/gtest-typed-test.h b/src/LLVM/utils/unittest/googletest/include/gtest/gtest-typed-test.h
new file mode 100644
index 0000000..1ec8eb8
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/include/gtest/gtest-typed-test.h
@@ -0,0 +1,259 @@
+// Copyright 2008 Google Inc.
+// All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
+#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
+
+// This header implements typed tests and type-parameterized tests.
+
+// Typed (aka type-driven) tests repeat the same test for types in a
+// list.  You must know which types you want to test with when writing
+// typed tests. Here's how you do it:
+
+#if 0
+
+// First, define a fixture class template.  It should be parameterized
+// by a type.  Remember to derive it from testing::Test.
+template <typename T>
+class FooTest : public testing::Test {
+ public:
+  ...
+  typedef std::list<T> List;
+  static T shared_;
+  T value_;
+};
+
+// Next, associate a list of types with the test case, which will be
+// repeated for each type in the list.  The typedef is necessary for
+// the macro to parse correctly.
+typedef testing::Types<char, int, unsigned int> MyTypes;
+TYPED_TEST_CASE(FooTest, MyTypes);
+
+// If the type list contains only one type, you can write that type
+// directly without Types<...>:
+//   TYPED_TEST_CASE(FooTest, int);
+
+// Then, use TYPED_TEST() instead of TEST_F() to define as many typed
+// tests for this test case as you want.
+TYPED_TEST(FooTest, DoesBlah) {
+  // Inside a test, refer to TypeParam to get the type parameter.
+  // Since we are inside a derived class template, C++ requires use to
+  // visit the members of FooTest via 'this'.
+  TypeParam n = this->value_;
+
+  // To visit static members of the fixture, add the TestFixture::
+  // prefix.
+  n += TestFixture::shared_;
+
+  // To refer to typedefs in the fixture, add the "typename
+  // TestFixture::" prefix.
+  typename TestFixture::List values;
+  values.push_back(n);
+  ...
+}
+
+TYPED_TEST(FooTest, HasPropertyA) { ... }
+
+#endif  // 0
+
+// Type-parameterized tests are abstract test patterns parameterized
+// by a type.  Compared with typed tests, type-parameterized tests
+// allow you to define the test pattern without knowing what the type
+// parameters are.  The defined pattern can be instantiated with
+// different types any number of times, in any number of translation
+// units.
+//
+// If you are designing an interface or concept, you can define a
+// suite of type-parameterized tests to verify properties that any
+// valid implementation of the interface/concept should have.  Then,
+// each implementation can easily instantiate the test suite to verify
+// that it conforms to the requirements, without having to write
+// similar tests repeatedly.  Here's an example:
+
+#if 0
+
+// First, define a fixture class template.  It should be parameterized
+// by a type.  Remember to derive it from testing::Test.
+template <typename T>
+class FooTest : public testing::Test {
+  ...
+};
+
+// Next, declare that you will define a type-parameterized test case
+// (the _P suffix is for "parameterized" or "pattern", whichever you
+// prefer):
+TYPED_TEST_CASE_P(FooTest);
+
+// Then, use TYPED_TEST_P() to define as many type-parameterized tests
+// for this type-parameterized test case as you want.
+TYPED_TEST_P(FooTest, DoesBlah) {
+  // Inside a test, refer to TypeParam to get the type parameter.
+  TypeParam n = 0;
+  ...
+}
+
+TYPED_TEST_P(FooTest, HasPropertyA) { ... }
+
+// Now the tricky part: you need to register all test patterns before
+// you can instantiate them.  The first argument of the macro is the
+// test case name; the rest are the names of the tests in this test
+// case.
+REGISTER_TYPED_TEST_CASE_P(FooTest,
+                           DoesBlah, HasPropertyA);
+
+// Finally, you are free to instantiate the pattern with the types you
+// want.  If you put the above code in a header file, you can #include
+// it in multiple C++ source files and instantiate it multiple times.
+//
+// To distinguish different instances of the pattern, the first
+// argument to the INSTANTIATE_* macro is a prefix that will be added
+// to the actual test case name.  Remember to pick unique prefixes for
+// different instances.
+typedef testing::Types<char, int, unsigned int> MyTypes;
+INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
+
+// If the type list contains only one type, you can write that type
+// directly without Types<...>:
+//   INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);
+
+#endif  // 0
+
+#include <gtest/internal/gtest-port.h>
+#include <gtest/internal/gtest-type-util.h>
+
+// Implements typed tests.
+
+#if GTEST_HAS_TYPED_TEST
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Expands to the name of the typedef for the type parameters of the
+// given test case.
+#define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_
+
+// The 'Types' template argument below must have spaces around it
+// since some compilers may choke on '>>' when passing a template
+// instance (e.g. Types<int>)
+#define TYPED_TEST_CASE(CaseName, Types) \
+  typedef ::testing::internal::TypeList< Types >::type \
+      GTEST_TYPE_PARAMS_(CaseName)
+
+#define TYPED_TEST(CaseName, TestName) \
+  template <typename gtest_TypeParam_> \
+  class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
+      : public CaseName<gtest_TypeParam_> { \
+   private: \
+    typedef CaseName<gtest_TypeParam_> TestFixture; \
+    typedef gtest_TypeParam_ TypeParam; \
+    virtual void TestBody(); \
+  }; \
+  bool gtest_##CaseName##_##TestName##_registered_ = \
+      ::testing::internal::TypeParameterizedTest< \
+          CaseName, \
+          ::testing::internal::TemplateSel< \
+              GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \
+          GTEST_TYPE_PARAMS_(CaseName)>::Register(\
+              "", #CaseName, #TestName, 0); \
+  template <typename gtest_TypeParam_> \
+  void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody()
+
+#endif  // GTEST_HAS_TYPED_TEST
+
+// Implements type-parameterized tests.
+
+#if GTEST_HAS_TYPED_TEST_P
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Expands to the namespace name that the type-parameterized tests for
+// the given type-parameterized test case are defined in.  The exact
+// name of the namespace is subject to change without notice.
+#define GTEST_CASE_NAMESPACE_(TestCaseName) \
+  gtest_case_##TestCaseName##_
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Expands to the name of the variable used to remember the names of
+// the defined tests in the given test case.
+#define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \
+  gtest_typed_test_case_p_state_##TestCaseName##_
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
+//
+// Expands to the name of the variable used to remember the names of
+// the registered tests in the given test case.
+#define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \
+  gtest_registered_test_names_##TestCaseName##_
+
+// The variables defined in the type-parameterized test macros are
+// static as typically these macros are used in a .h file that can be
+// #included in multiple translation units linked together.
+#define TYPED_TEST_CASE_P(CaseName) \
+  static ::testing::internal::TypedTestCasePState \
+      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName)
+
+#define TYPED_TEST_P(CaseName, TestName) \
+  namespace GTEST_CASE_NAMESPACE_(CaseName) { \
+  template <typename gtest_TypeParam_> \
+  class TestName : public CaseName<gtest_TypeParam_> { \
+   private: \
+    typedef CaseName<gtest_TypeParam_> TestFixture; \
+    typedef gtest_TypeParam_ TypeParam; \
+    virtual void TestBody(); \
+  }; \
+  static bool gtest_##TestName##_defined_ = \
+      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\
+          __FILE__, __LINE__, #CaseName, #TestName); \
+  } \
+  template <typename gtest_TypeParam_> \
+  void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody()
+
+#define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \
+  namespace GTEST_CASE_NAMESPACE_(CaseName) { \
+  typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
+  } \
+  static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \
+      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\
+          __FILE__, __LINE__, #__VA_ARGS__)
+
+// The 'Types' template argument below must have spaces around it
+// since some compilers may choke on '>>' when passing a template
+// instance (e.g. Types<int>)
+#define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \
+  bool gtest_##Prefix##_##CaseName = \
+      ::testing::internal::TypeParameterizedTestCase<CaseName, \
+          GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
+          ::testing::internal::TypeList< Types >::type>::Register(\
+              #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
+
+#endif  // GTEST_HAS_TYPED_TEST_P
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
diff --git a/src/LLVM/utils/unittest/googletest/include/gtest/gtest.h b/src/LLVM/utils/unittest/googletest/include/gtest/gtest.h
new file mode 100644
index 0000000..921fad1
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/include/gtest/gtest.h
@@ -0,0 +1,2052 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file defines the public API for Google Test.  It should be
+// included by any test program that uses Google Test.
+//
+// IMPORTANT NOTE: Due to limitation of the C++ language, we have to
+// leave some internal implementation details in this header file.
+// They are clearly marked by comments like this:
+//
+//   // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+//
+// Such code is NOT meant to be used by a user directly, and is subject
+// to CHANGE WITHOUT NOTICE.  Therefore DO NOT DEPEND ON IT in a user
+// program!
+//
+// Acknowledgment: Google Test borrowed the idea of automatic test
+// registration from Barthelemy Dagenais' (barthelemy@prologique.com)
+// easyUnit framework.
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
+#define GTEST_INCLUDE_GTEST_GTEST_H_
+
+#include <limits>
+#include <vector>
+
+#include <gtest/internal/gtest-internal.h>
+#include <gtest/internal/gtest-string.h>
+#include <gtest/gtest-death-test.h>
+#include <gtest/gtest-message.h>
+#include <gtest/gtest-param-test.h>
+#include <gtest/gtest_prod.h>
+#include <gtest/gtest-test-part.h>
+#include <gtest/gtest-typed-test.h>
+
+// Depending on the platform, different string classes are available.
+// On Linux, in addition to ::std::string, Google also makes use of
+// class ::string, which has the same interface as ::std::string, but
+// has a different implementation.
+//
+// The user can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that
+// ::string is available AND is a distinct type to ::std::string, or
+// define it to 0 to indicate otherwise.
+//
+// If the user's ::std::string and ::string are the same class due to
+// aliasing, he should define GTEST_HAS_GLOBAL_STRING to 0.
+//
+// If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined
+// heuristically.
+
+namespace testing {
+
+// Declares the flags.
+
+// This flag temporary enables the disabled tests.
+GTEST_DECLARE_bool_(also_run_disabled_tests);
+
+// This flag brings the debugger on an assertion failure.
+GTEST_DECLARE_bool_(break_on_failure);
+
+// This flag controls whether Google Test catches all test-thrown exceptions
+// and logs them as failures.
+GTEST_DECLARE_bool_(catch_exceptions);
+
+// This flag enables using colors in terminal output. Available values are
+// "yes" to enable colors, "no" (disable colors), or "auto" (the default)
+// to let Google Test decide.
+GTEST_DECLARE_string_(color);
+
+// This flag sets up the filter to select by name using a glob pattern
+// the tests to run. If the filter is not given all tests are executed.
+GTEST_DECLARE_string_(filter);
+
+// This flag causes the Google Test to list tests. None of the tests listed
+// are actually run if the flag is provided.
+GTEST_DECLARE_bool_(list_tests);
+
+// This flag controls whether Google Test emits a detailed XML report to a file
+// in addition to its normal textual output.
+GTEST_DECLARE_string_(output);
+
+// This flags control whether Google Test prints the elapsed time for each
+// test.
+GTEST_DECLARE_bool_(print_time);
+
+// This flag specifies the random number seed.
+GTEST_DECLARE_int32_(random_seed);
+
+// This flag sets how many times the tests are repeated. The default value
+// is 1. If the value is -1 the tests are repeating forever.
+GTEST_DECLARE_int32_(repeat);
+
+// This flag controls whether Google Test includes Google Test internal
+// stack frames in failure stack traces.
+GTEST_DECLARE_bool_(show_internal_stack_frames);
+
+// When this flag is specified, tests' order is randomized on every iteration.
+GTEST_DECLARE_bool_(shuffle);
+
+// This flag specifies the maximum number of stack frames to be
+// printed in a failure message.
+GTEST_DECLARE_int32_(stack_trace_depth);
+
+// When this flag is specified, a failed assertion will throw an
+// exception if exceptions are enabled, or exit the program with a
+// non-zero code otherwise.
+GTEST_DECLARE_bool_(throw_on_failure);
+
+// The upper limit for valid stack trace depths.
+const int kMaxStackTraceDepth = 100;
+
+namespace internal {
+
+class AssertHelper;
+class DefaultGlobalTestPartResultReporter;
+class ExecDeathTest;
+class NoExecDeathTest;
+class FinalSuccessChecker;
+class GTestFlagSaver;
+class TestInfoImpl;
+class TestResultAccessor;
+class TestEventListenersAccessor;
+class TestEventRepeater;
+class WindowsDeathTest;
+class UnitTestImpl* GetUnitTestImpl();
+void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
+                                    const String& message);
+class PrettyUnitTestResultPrinter;
+class XmlUnitTestResultPrinter;
+
+// Converts a streamable value to a String.  A NULL pointer is
+// converted to "(null)".  When the input value is a ::string,
+// ::std::string, ::wstring, or ::std::wstring object, each NUL
+// character in it is replaced with "\\0".
+// Declared in gtest-internal.h but defined here, so that it has access
+// to the definition of the Message class, required by the ARM
+// compiler.
+template <typename T>
+String StreamableToString(const T& streamable) {
+  return (Message() << streamable).GetString();
+}
+
+}  // namespace internal
+
+// A class for indicating whether an assertion was successful.  When
+// the assertion wasn't successful, the AssertionResult object
+// remembers a non-empty message that describes how it failed.
+//
+// To create an instance of this class, use one of the factory functions
+// (AssertionSuccess() and AssertionFailure()).
+//
+// This class is useful for two purposes:
+//   1. Defining predicate functions to be used with Boolean test assertions
+//      EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts
+//   2. Defining predicate-format functions to be
+//      used with predicate assertions (ASSERT_PRED_FORMAT*, etc).
+//
+// For example, if you define IsEven predicate:
+//
+//   testing::AssertionResult IsEven(int n) {
+//     if ((n % 2) == 0)
+//       return testing::AssertionSuccess();
+//     else
+//       return testing::AssertionFailure() << n << " is odd";
+//   }
+//
+// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5)))
+// will print the message
+//
+//   Value of: IsEven(Fib(5))
+//     Actual: false (5 is odd)
+//   Expected: true
+//
+// instead of a more opaque
+//
+//   Value of: IsEven(Fib(5))
+//     Actual: false
+//   Expected: true
+//
+// in case IsEven is a simple Boolean predicate.
+//
+// If you expect your predicate to be reused and want to support informative
+// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up
+// about half as often as positive ones in our tests), supply messages for
+// both success and failure cases:
+//
+//   testing::AssertionResult IsEven(int n) {
+//     if ((n % 2) == 0)
+//       return testing::AssertionSuccess() << n << " is even";
+//     else
+//       return testing::AssertionFailure() << n << " is odd";
+//   }
+//
+// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print
+//
+//   Value of: IsEven(Fib(6))
+//     Actual: true (8 is even)
+//   Expected: false
+//
+// NB: Predicates that support negative Boolean assertions have reduced
+// performance in positive ones so be careful not to use them in tests
+// that have lots (tens of thousands) of positive Boolean assertions.
+//
+// To use this class with EXPECT_PRED_FORMAT assertions such as:
+//
+//   // Verifies that Foo() returns an even number.
+//   EXPECT_PRED_FORMAT1(IsEven, Foo());
+//
+// you need to define:
+//
+//   testing::AssertionResult IsEven(const char* expr, int n) {
+//     if ((n % 2) == 0)
+//       return testing::AssertionSuccess();
+//     else
+//       return testing::AssertionFailure()
+//         << "Expected: " << expr << " is even\n  Actual: it's " << n;
+//   }
+//
+// If Foo() returns 5, you will see the following message:
+//
+//   Expected: Foo() is even
+//     Actual: it's 5
+//
+class GTEST_API_ AssertionResult {
+ public:
+  // Copy constructor.
+  // Used in EXPECT_TRUE/FALSE(assertion_result).
+  AssertionResult(const AssertionResult& other);
+  // Used in the EXPECT_TRUE/FALSE(bool_expression).
+  explicit AssertionResult(bool success) : success_(success) {}
+
+  // Returns true iff the assertion succeeded.
+  operator bool() const { return success_; }  // NOLINT
+
+  // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
+  AssertionResult operator!() const;
+
+  // Returns the text streamed into this AssertionResult. Test assertions
+  // use it when they fail (i.e., the predicate's outcome doesn't match the
+  // assertion's expectation). When nothing has been streamed into the
+  // object, returns an empty string.
+  const char* message() const {
+    return message_.get() != NULL && message_->c_str() != NULL ?
+           message_->c_str() : "";
+  }
+  // TODO(vladl@google.com): Remove this after making sure no clients use it.
+  // Deprecated; please use message() instead.
+  const char* failure_message() const { return message(); }
+
+  // Streams a custom failure message into this object.
+  template <typename T> AssertionResult& operator<<(const T& value);
+
+ private:
+  // No implementation - we want AssertionResult to be
+  // copy-constructible but not assignable.
+  void operator=(const AssertionResult& other);
+
+  // Stores result of the assertion predicate.
+  bool success_;
+  // Stores the message describing the condition in case the expectation
+  // construct is not satisfied with the predicate's outcome.
+  // Referenced via a pointer to avoid taking too much stack frame space
+  // with test assertions.
+  internal::scoped_ptr<internal::String> message_;
+};  // class AssertionResult
+
+// Streams a custom failure message into this object.
+template <typename T>
+AssertionResult& AssertionResult::operator<<(const T& value) {
+  Message msg;
+  if (message_.get() != NULL)
+    msg << *message_;
+  msg << value;
+  message_.reset(new internal::String(msg.GetString()));
+  return *this;
+}
+
+// Makes a successful assertion result.
+GTEST_API_ AssertionResult AssertionSuccess();
+
+// Makes a failed assertion result.
+GTEST_API_ AssertionResult AssertionFailure();
+
+// Makes a failed assertion result with the given failure message.
+// Deprecated; use AssertionFailure() << msg.
+GTEST_API_ AssertionResult AssertionFailure(const Message& msg);
+
+// The abstract class that all tests inherit from.
+//
+// In Google Test, a unit test program contains one or many TestCases, and
+// each TestCase contains one or many Tests.
+//
+// When you define a test using the TEST macro, you don't need to
+// explicitly derive from Test - the TEST macro automatically does
+// this for you.
+//
+// The only time you derive from Test is when defining a test fixture
+// to be used a TEST_F.  For example:
+//
+//   class FooTest : public testing::Test {
+//    protected:
+//     virtual void SetUp() { ... }
+//     virtual void TearDown() { ... }
+//     ...
+//   };
+//
+//   TEST_F(FooTest, Bar) { ... }
+//   TEST_F(FooTest, Baz) { ... }
+//
+// Test is not copyable.
+class GTEST_API_ Test {
+ public:
+  friend class internal::TestInfoImpl;
+
+  // Defines types for pointers to functions that set up and tear down
+  // a test case.
+  typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc;
+  typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc;
+
+  // The d'tor is virtual as we intend to inherit from Test.
+  virtual ~Test();
+
+  // Sets up the stuff shared by all tests in this test case.
+  //
+  // Google Test will call Foo::SetUpTestCase() before running the first
+  // test in test case Foo.  Hence a sub-class can define its own
+  // SetUpTestCase() method to shadow the one defined in the super
+  // class.
+  static void SetUpTestCase() {}
+
+  // Tears down the stuff shared by all tests in this test case.
+  //
+  // Google Test will call Foo::TearDownTestCase() after running the last
+  // test in test case Foo.  Hence a sub-class can define its own
+  // TearDownTestCase() method to shadow the one defined in the super
+  // class.
+  static void TearDownTestCase() {}
+
+  // Returns true iff the current test has a fatal failure.
+  static bool HasFatalFailure();
+
+  // Returns true iff the current test has a non-fatal failure.
+  static bool HasNonfatalFailure();
+
+  // Returns true iff the current test has a (either fatal or
+  // non-fatal) failure.
+  static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); }
+
+  // Logs a property for the current test.  Only the last value for a given
+  // key is remembered.
+  // These are public static so they can be called from utility functions
+  // that are not members of the test fixture.
+  // The arguments are const char* instead strings, as Google Test is used
+  // on platforms where string doesn't compile.
+  //
+  // Note that a driving consideration for these RecordProperty methods
+  // was to produce xml output suited to the Greenspan charting utility,
+  // which at present will only chart values that fit in a 32-bit int. It
+  // is the user's responsibility to restrict their values to 32-bit ints
+  // if they intend them to be used with Greenspan.
+  static void RecordProperty(const char* key, const char* value);
+  static void RecordProperty(const char* key, int value);
+
+ protected:
+  // Creates a Test object.
+  Test();
+
+  // Sets up the test fixture.
+  virtual void SetUp();
+
+  // Tears down the test fixture.
+  virtual void TearDown();
+
+ private:
+  // Returns true iff the current test has the same fixture class as
+  // the first test in the current test case.
+  static bool HasSameFixtureClass();
+
+  // Runs the test after the test fixture has been set up.
+  //
+  // A sub-class must implement this to define the test logic.
+  //
+  // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM.
+  // Instead, use the TEST or TEST_F macro.
+  virtual void TestBody() = 0;
+
+  // Sets up, executes, and tears down the test.
+  void Run();
+
+  // Uses a GTestFlagSaver to save and restore all Google Test flags.
+  const internal::GTestFlagSaver* const gtest_flag_saver_;
+
+  // Often a user mis-spells SetUp() as Setup() and spends a long time
+  // wondering why it is never called by Google Test.  The declaration of
+  // the following method is solely for catching such an error at
+  // compile time:
+  //
+  //   - The return type is deliberately chosen to be not void, so it
+  //   will be a conflict if a user declares void Setup() in his test
+  //   fixture.
+  //
+  //   - This method is private, so it will be another compiler error
+  //   if a user calls it from his test fixture.
+  //
+  // DO NOT OVERRIDE THIS FUNCTION.
+  //
+  // If you see an error about overriding the following function or
+  // about it being private, you have mis-spelled SetUp() as Setup().
+  struct Setup_should_be_spelled_SetUp {};
+  virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }
+
+  // We disallow copying Tests.
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(Test);
+};
+
+typedef internal::TimeInMillis TimeInMillis;
+
+// A copyable object representing a user specified test property which can be
+// output as a key/value string pair.
+//
+// Don't inherit from TestProperty as its destructor is not virtual.
+class TestProperty {
+ public:
+  // C'tor.  TestProperty does NOT have a default constructor.
+  // Always use this constructor (with parameters) to create a
+  // TestProperty object.
+  TestProperty(const char* a_key, const char* a_value) :
+    key_(a_key), value_(a_value) {
+  }
+
+  // Gets the user supplied key.
+  const char* key() const {
+    return key_.c_str();
+  }
+
+  // Gets the user supplied value.
+  const char* value() const {
+    return value_.c_str();
+  }
+
+  // Sets a new value, overriding the one supplied in the constructor.
+  void SetValue(const char* new_value) {
+    value_ = new_value;
+  }
+
+ private:
+  // The key supplied by the user.
+  internal::String key_;
+  // The value supplied by the user.
+  internal::String value_;
+};
+
+// The result of a single Test.  This includes a list of
+// TestPartResults, a list of TestProperties, a count of how many
+// death tests there are in the Test, and how much time it took to run
+// the Test.
+//
+// TestResult is not copyable.
+class GTEST_API_ TestResult {
+ public:
+  // Creates an empty TestResult.
+  TestResult();
+
+  // D'tor.  Do not inherit from TestResult.
+  ~TestResult();
+
+  // Gets the number of all test parts.  This is the sum of the number
+  // of successful test parts and the number of failed test parts.
+  int total_part_count() const;
+
+  // Returns the number of the test properties.
+  int test_property_count() const;
+
+  // Returns true iff the test passed (i.e. no test part failed).
+  bool Passed() const { return !Failed(); }
+
+  // Returns true iff the test failed.
+  bool Failed() const;
+
+  // Returns true iff the test fatally failed.
+  bool HasFatalFailure() const;
+
+  // Returns true iff the test has a non-fatal failure.
+  bool HasNonfatalFailure() const;
+
+  // Returns the elapsed time, in milliseconds.
+  TimeInMillis elapsed_time() const { return elapsed_time_; }
+
+  // Returns the i-th test part result among all the results. i can range
+  // from 0 to test_property_count() - 1. If i is not in that range, aborts
+  // the program.
+  const TestPartResult& GetTestPartResult(int i) const;
+
+  // Returns the i-th test property. i can range from 0 to
+  // test_property_count() - 1. If i is not in that range, aborts the
+  // program.
+  const TestProperty& GetTestProperty(int i) const;
+
+ private:
+  friend class TestInfo;
+  friend class UnitTest;
+  friend class internal::DefaultGlobalTestPartResultReporter;
+  friend class internal::ExecDeathTest;
+  friend class internal::TestInfoImpl;
+  friend class internal::TestResultAccessor;
+  friend class internal::UnitTestImpl;
+  friend class internal::WindowsDeathTest;
+
+  // Gets the vector of TestPartResults.
+  const std::vector<TestPartResult>& test_part_results() const {
+    return test_part_results_;
+  }
+
+  // Gets the vector of TestProperties.
+  const std::vector<TestProperty>& test_properties() const {
+    return test_properties_;
+  }
+
+  // Sets the elapsed time.
+  void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; }
+
+  // Adds a test property to the list. The property is validated and may add
+  // a non-fatal failure if invalid (e.g., if it conflicts with reserved
+  // key names). If a property is already recorded for the same key, the
+  // value will be updated, rather than storing multiple values for the same
+  // key.
+  void RecordProperty(const TestProperty& test_property);
+
+  // Adds a failure if the key is a reserved attribute of Google Test
+  // testcase tags.  Returns true if the property is valid.
+  // TODO(russr): Validate attribute names are legal and human readable.
+  static bool ValidateTestProperty(const TestProperty& test_property);
+
+  // Adds a test part result to the list.
+  void AddTestPartResult(const TestPartResult& test_part_result);
+
+  // Returns the death test count.
+  int death_test_count() const { return death_test_count_; }
+
+  // Increments the death test count, returning the new count.
+  int increment_death_test_count() { return ++death_test_count_; }
+
+  // Clears the test part results.
+  void ClearTestPartResults();
+
+  // Clears the object.
+  void Clear();
+
+  // Protects mutable state of the property vector and of owned
+  // properties, whose values may be updated.
+  internal::Mutex test_properites_mutex_;
+
+  // The vector of TestPartResults
+  std::vector<TestPartResult> test_part_results_;
+  // The vector of TestProperties
+  std::vector<TestProperty> test_properties_;
+  // Running count of death tests.
+  int death_test_count_;
+  // The elapsed time, in milliseconds.
+  TimeInMillis elapsed_time_;
+
+  // We disallow copying TestResult.
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult);
+};  // class TestResult
+
+// A TestInfo object stores the following information about a test:
+//
+//   Test case name
+//   Test name
+//   Whether the test should be run
+//   A function pointer that creates the test object when invoked
+//   Test result
+//
+// The constructor of TestInfo registers itself with the UnitTest
+// singleton such that the RUN_ALL_TESTS() macro knows which tests to
+// run.
+class GTEST_API_ TestInfo {
+ public:
+  // Destructs a TestInfo object.  This function is not virtual, so
+  // don't inherit from TestInfo.
+  ~TestInfo();
+
+  // Returns the test case name.
+  const char* test_case_name() const;
+
+  // Returns the test name.
+  const char* name() const;
+
+  // Returns the test case comment.
+  const char* test_case_comment() const;
+
+  // Returns the test comment.
+  const char* comment() const;
+
+  // Returns true if this test should run, that is if the test is not disabled
+  // (or it is disabled but the also_run_disabled_tests flag has been specified)
+  // and its full name matches the user-specified filter.
+  //
+  // Google Test allows the user to filter the tests by their full names.
+  // The full name of a test Bar in test case Foo is defined as
+  // "Foo.Bar".  Only the tests that match the filter will run.
+  //
+  // A filter is a colon-separated list of glob (not regex) patterns,
+  // optionally followed by a '-' and a colon-separated list of
+  // negative patterns (tests to exclude).  A test is run if it
+  // matches one of the positive patterns and does not match any of
+  // the negative patterns.
+  //
+  // For example, *A*:Foo.* is a filter that matches any string that
+  // contains the character 'A' or starts with "Foo.".
+  bool should_run() const;
+
+  // Returns the result of the test.
+  const TestResult* result() const;
+
+ private:
+#if GTEST_HAS_DEATH_TEST
+  friend class internal::DefaultDeathTestFactory;
+#endif  // GTEST_HAS_DEATH_TEST
+  friend class Test;
+  friend class TestCase;
+  friend class internal::TestInfoImpl;
+  friend class internal::UnitTestImpl;
+  friend TestInfo* internal::MakeAndRegisterTestInfo(
+      const char* test_case_name, const char* name,
+      const char* test_case_comment, const char* comment,
+      internal::TypeId fixture_class_id,
+      Test::SetUpTestCaseFunc set_up_tc,
+      Test::TearDownTestCaseFunc tear_down_tc,
+      internal::TestFactoryBase* factory);
+
+  // Returns true if this test matches the user-specified filter.
+  bool matches_filter() const;
+
+  // Increments the number of death tests encountered in this test so
+  // far.
+  int increment_death_test_count();
+
+  // Accessors for the implementation object.
+  internal::TestInfoImpl* impl() { return impl_; }
+  const internal::TestInfoImpl* impl() const { return impl_; }
+
+  // Constructs a TestInfo object. The newly constructed instance assumes
+  // ownership of the factory object.
+  TestInfo(const char* test_case_name, const char* name,
+           const char* test_case_comment, const char* comment,
+           internal::TypeId fixture_class_id,
+           internal::TestFactoryBase* factory);
+
+  // An opaque implementation object.
+  internal::TestInfoImpl* impl_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo);
+};
+
+// A test case, which consists of a vector of TestInfos.
+//
+// TestCase is not copyable.
+class GTEST_API_ TestCase {
+ public:
+  // Creates a TestCase with the given name.
+  //
+  // TestCase does NOT have a default constructor.  Always use this
+  // constructor to create a TestCase object.
+  //
+  // Arguments:
+  //
+  //   name:         name of the test case
+  //   set_up_tc:    pointer to the function that sets up the test case
+  //   tear_down_tc: pointer to the function that tears down the test case
+  TestCase(const char* name, const char* comment,
+           Test::SetUpTestCaseFunc set_up_tc,
+           Test::TearDownTestCaseFunc tear_down_tc);
+
+  // Destructor of TestCase.
+  virtual ~TestCase();
+
+  // Gets the name of the TestCase.
+  const char* name() const { return name_.c_str(); }
+
+  // Returns the test case comment.
+  const char* comment() const { return comment_.c_str(); }
+
+  // Returns true if any test in this test case should run.
+  bool should_run() const { return should_run_; }
+
+  // Gets the number of successful tests in this test case.
+  int successful_test_count() const;
+
+  // Gets the number of failed tests in this test case.
+  int failed_test_count() const;
+
+  // Gets the number of disabled tests in this test case.
+  int disabled_test_count() const;
+
+  // Get the number of tests in this test case that should run.
+  int test_to_run_count() const;
+
+  // Gets the number of all tests in this test case.
+  int total_test_count() const;
+
+  // Returns true iff the test case passed.
+  bool Passed() const { return !Failed(); }
+
+  // Returns true iff the test case failed.
+  bool Failed() const { return failed_test_count() > 0; }
+
+  // Returns the elapsed time, in milliseconds.
+  TimeInMillis elapsed_time() const { return elapsed_time_; }
+
+  // Returns the i-th test among all the tests. i can range from 0 to
+  // total_test_count() - 1. If i is not in that range, returns NULL.
+  const TestInfo* GetTestInfo(int i) const;
+
+ private:
+  friend class Test;
+  friend class internal::UnitTestImpl;
+
+  // Gets the (mutable) vector of TestInfos in this TestCase.
+  std::vector<TestInfo*>& test_info_list() { return test_info_list_; }
+
+  // Gets the (immutable) vector of TestInfos in this TestCase.
+  const std::vector<TestInfo*>& test_info_list() const {
+    return test_info_list_;
+  }
+
+  // Returns the i-th test among all the tests. i can range from 0 to
+  // total_test_count() - 1. If i is not in that range, returns NULL.
+  TestInfo* GetMutableTestInfo(int i);
+
+  // Sets the should_run member.
+  void set_should_run(bool should) { should_run_ = should; }
+
+  // Adds a TestInfo to this test case.  Will delete the TestInfo upon
+  // destruction of the TestCase object.
+  void AddTestInfo(TestInfo * test_info);
+
+  // Clears the results of all tests in this test case.
+  void ClearResult();
+
+  // Clears the results of all tests in the given test case.
+  static void ClearTestCaseResult(TestCase* test_case) {
+    test_case->ClearResult();
+  }
+
+  // Runs every test in this TestCase.
+  void Run();
+
+  // Returns true iff test passed.
+  static bool TestPassed(const TestInfo * test_info);
+
+  // Returns true iff test failed.
+  static bool TestFailed(const TestInfo * test_info);
+
+  // Returns true iff test is disabled.
+  static bool TestDisabled(const TestInfo * test_info);
+
+  // Returns true if the given test should run.
+  static bool ShouldRunTest(const TestInfo *test_info);
+
+  // Shuffles the tests in this test case.
+  void ShuffleTests(internal::Random* random);
+
+  // Restores the test order to before the first shuffle.
+  void UnshuffleTests();
+
+  // Name of the test case.
+  internal::String name_;
+  // Comment on the test case.
+  internal::String comment_;
+  // The vector of TestInfos in their original order.  It owns the
+  // elements in the vector.
+  std::vector<TestInfo*> test_info_list_;
+  // Provides a level of indirection for the test list to allow easy
+  // shuffling and restoring the test order.  The i-th element in this
+  // vector is the index of the i-th test in the shuffled test list.
+  std::vector<int> test_indices_;
+  // Pointer to the function that sets up the test case.
+  Test::SetUpTestCaseFunc set_up_tc_;
+  // Pointer to the function that tears down the test case.
+  Test::TearDownTestCaseFunc tear_down_tc_;
+  // True iff any test in this test case should run.
+  bool should_run_;
+  // Elapsed time, in milliseconds.
+  TimeInMillis elapsed_time_;
+
+  // We disallow copying TestCases.
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase);
+};
+
+// An Environment object is capable of setting up and tearing down an
+// environment.  The user should subclass this to define his own
+// environment(s).
+//
+// An Environment object does the set-up and tear-down in virtual
+// methods SetUp() and TearDown() instead of the constructor and the
+// destructor, as:
+//
+//   1. You cannot safely throw from a destructor.  This is a problem
+//      as in some cases Google Test is used where exceptions are enabled, and
+//      we may want to implement ASSERT_* using exceptions where they are
+//      available.
+//   2. You cannot use ASSERT_* directly in a constructor or
+//      destructor.
+class Environment {
+ public:
+  // The d'tor is virtual as we need to subclass Environment.
+  virtual ~Environment() {}
+
+  // Override this to define how to set up the environment.
+  virtual void SetUp() {}
+
+  // Override this to define how to tear down the environment.
+  virtual void TearDown() {}
+ private:
+  // If you see an error about overriding the following function or
+  // about it being private, you have mis-spelled SetUp() as Setup().
+  struct Setup_should_be_spelled_SetUp {};
+  virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }
+};
+
+// The interface for tracing execution of tests. The methods are organized in
+// the order the corresponding events are fired.
+class TestEventListener {
+ public:
+  virtual ~TestEventListener() {}
+
+  // Fired before any test activity starts.
+  virtual void OnTestProgramStart(const UnitTest& unit_test) = 0;
+
+  // Fired before each iteration of tests starts.  There may be more than
+  // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration
+  // index, starting from 0.
+  virtual void OnTestIterationStart(const UnitTest& unit_test,
+                                    int iteration) = 0;
+
+  // Fired before environment set-up for each iteration of tests starts.
+  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0;
+
+  // Fired after environment set-up for each iteration of tests ends.
+  virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0;
+
+  // Fired before the test case starts.
+  virtual void OnTestCaseStart(const TestCase& test_case) = 0;
+
+  // Fired before the test starts.
+  virtual void OnTestStart(const TestInfo& test_info) = 0;
+
+  // Fired after a failed assertion or a SUCCESS().
+  virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0;
+
+  // Fired after the test ends.
+  virtual void OnTestEnd(const TestInfo& test_info) = 0;
+
+  // Fired after the test case ends.
+  virtual void OnTestCaseEnd(const TestCase& test_case) = 0;
+
+  // Fired before environment tear-down for each iteration of tests starts.
+  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0;
+
+  // Fired after environment tear-down for each iteration of tests ends.
+  virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0;
+
+  // Fired after each iteration of tests finishes.
+  virtual void OnTestIterationEnd(const UnitTest& unit_test,
+                                  int iteration) = 0;
+
+  // Fired after all test activities have ended.
+  virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0;
+};
+
+// The convenience class for users who need to override just one or two
+// methods and are not concerned that a possible change to a signature of
+// the methods they override will not be caught during the build.  For
+// comments about each method please see the definition of TestEventListener
+// above.
+class EmptyTestEventListener : public TestEventListener {
+ public:
+  virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestIterationStart(const UnitTest& /*unit_test*/,
+                                    int /*iteration*/) {}
+  virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {}
+  virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}
+  virtual void OnTestStart(const TestInfo& /*test_info*/) {}
+  virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {}
+  virtual void OnTestEnd(const TestInfo& /*test_info*/) {}
+  virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {}
+  virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {}
+  virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/,
+                                  int /*iteration*/) {}
+  virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}
+};
+
+// TestEventListeners lets users add listeners to track events in Google Test.
+class GTEST_API_ TestEventListeners {
+ public:
+  TestEventListeners();
+  ~TestEventListeners();
+
+  // Appends an event listener to the end of the list. Google Test assumes
+  // the ownership of the listener (i.e. it will delete the listener when
+  // the test program finishes).
+  void Append(TestEventListener* listener);
+
+  // Removes the given event listener from the list and returns it.  It then
+  // becomes the caller's responsibility to delete the listener. Returns
+  // NULL if the listener is not found in the list.
+  TestEventListener* Release(TestEventListener* listener);
+
+  // Returns the standard listener responsible for the default console
+  // output.  Can be removed from the listeners list to shut down default
+  // console output.  Note that removing this object from the listener list
+  // with Release transfers its ownership to the caller and makes this
+  // function return NULL the next time.
+  TestEventListener* default_result_printer() const {
+    return default_result_printer_;
+  }
+
+  // Returns the standard listener responsible for the default XML output
+  // controlled by the --gtest_output=xml flag.  Can be removed from the
+  // listeners list by users who want to shut down the default XML output
+  // controlled by this flag and substitute it with custom one.  Note that
+  // removing this object from the listener list with Release transfers its
+  // ownership to the caller and makes this function return NULL the next
+  // time.
+  TestEventListener* default_xml_generator() const {
+    return default_xml_generator_;
+  }
+
+ private:
+  friend class TestCase;
+  friend class internal::DefaultGlobalTestPartResultReporter;
+  friend class internal::NoExecDeathTest;
+  friend class internal::TestEventListenersAccessor;
+  friend class internal::TestInfoImpl;
+  friend class internal::UnitTestImpl;
+
+  // Returns repeater that broadcasts the TestEventListener events to all
+  // subscribers.
+  TestEventListener* repeater();
+
+  // Sets the default_result_printer attribute to the provided listener.
+  // The listener is also added to the listener list and previous
+  // default_result_printer is removed from it and deleted. The listener can
+  // also be NULL in which case it will not be added to the list. Does
+  // nothing if the previous and the current listener objects are the same.
+  void SetDefaultResultPrinter(TestEventListener* listener);
+
+  // Sets the default_xml_generator attribute to the provided listener.  The
+  // listener is also added to the listener list and previous
+  // default_xml_generator is removed from it and deleted. The listener can
+  // also be NULL in which case it will not be added to the list. Does
+  // nothing if the previous and the current listener objects are the same.
+  void SetDefaultXmlGenerator(TestEventListener* listener);
+
+  // Controls whether events will be forwarded by the repeater to the
+  // listeners in the list.
+  bool EventForwardingEnabled() const;
+  void SuppressEventForwarding();
+
+  // The actual list of listeners.
+  internal::TestEventRepeater* repeater_;
+  // Listener responsible for the standard result output.
+  TestEventListener* default_result_printer_;
+  // Listener responsible for the creation of the XML output file.
+  TestEventListener* default_xml_generator_;
+
+  // We disallow copying TestEventListeners.
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners);
+};
+
+// A UnitTest consists of a vector of TestCases.
+//
+// This is a singleton class.  The only instance of UnitTest is
+// created when UnitTest::GetInstance() is first called.  This
+// instance is never deleted.
+//
+// UnitTest is not copyable.
+//
+// This class is thread-safe as long as the methods are called
+// according to their specification.
+class GTEST_API_ UnitTest {
+ public:
+  // Gets the singleton UnitTest object.  The first time this method
+  // is called, a UnitTest object is constructed and returned.
+  // Consecutive calls will return the same object.
+  static UnitTest* GetInstance();
+
+  // Runs all tests in this UnitTest object and prints the result.
+  // Returns 0 if successful, or 1 otherwise.
+  //
+  // This method can only be called from the main thread.
+  //
+  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+  int Run() GTEST_MUST_USE_RESULT_;
+
+  // Returns the working directory when the first TEST() or TEST_F()
+  // was executed.  The UnitTest object owns the string.
+  const char* original_working_dir() const;
+
+  // Returns the TestCase object for the test that's currently running,
+  // or NULL if no test is running.
+  const TestCase* current_test_case() const;
+
+  // Returns the TestInfo object for the test that's currently running,
+  // or NULL if no test is running.
+  const TestInfo* current_test_info() const;
+
+  // Returns the random seed used at the start of the current test run.
+  int random_seed() const;
+
+#if GTEST_HAS_PARAM_TEST
+  // Returns the ParameterizedTestCaseRegistry object used to keep track of
+  // value-parameterized tests and instantiate and register them.
+  //
+  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+  internal::ParameterizedTestCaseRegistry& parameterized_test_registry();
+#endif  // GTEST_HAS_PARAM_TEST
+
+  // Gets the number of successful test cases.
+  int successful_test_case_count() const;
+
+  // Gets the number of failed test cases.
+  int failed_test_case_count() const;
+
+  // Gets the number of all test cases.
+  int total_test_case_count() const;
+
+  // Gets the number of all test cases that contain at least one test
+  // that should run.
+  int test_case_to_run_count() const;
+
+  // Gets the number of successful tests.
+  int successful_test_count() const;
+
+  // Gets the number of failed tests.
+  int failed_test_count() const;
+
+  // Gets the number of disabled tests.
+  int disabled_test_count() const;
+
+  // Gets the number of all tests.
+  int total_test_count() const;
+
+  // Gets the number of tests that should run.
+  int test_to_run_count() const;
+
+  // Gets the elapsed time, in milliseconds.
+  TimeInMillis elapsed_time() const;
+
+  // Returns true iff the unit test passed (i.e. all test cases passed).
+  bool Passed() const;
+
+  // Returns true iff the unit test failed (i.e. some test case failed
+  // or something outside of all tests failed).
+  bool Failed() const;
+
+  // Gets the i-th test case among all the test cases. i can range from 0 to
+  // total_test_case_count() - 1. If i is not in that range, returns NULL.
+  const TestCase* GetTestCase(int i) const;
+
+  // Returns the list of event listeners that can be used to track events
+  // inside Google Test.
+  TestEventListeners& listeners();
+
+ private:
+  // Registers and returns a global test environment.  When a test
+  // program is run, all global test environments will be set-up in
+  // the order they were registered.  After all tests in the program
+  // have finished, all global test environments will be torn-down in
+  // the *reverse* order they were registered.
+  //
+  // The UnitTest object takes ownership of the given environment.
+  //
+  // This method can only be called from the main thread.
+  Environment* AddEnvironment(Environment* env);
+
+  // Adds a TestPartResult to the current TestResult object.  All
+  // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc)
+  // eventually call this to report their results.  The user code
+  // should use the assertion macros instead of calling this directly.
+  void AddTestPartResult(TestPartResult::Type result_type,
+                         const char* file_name,
+                         int line_number,
+                         const internal::String& message,
+                         const internal::String& os_stack_trace);
+
+  // Adds a TestProperty to the current TestResult object. If the result already
+  // contains a property with the same key, the value will be updated.
+  void RecordPropertyForCurrentTest(const char* key, const char* value);
+
+  // Gets the i-th test case among all the test cases. i can range from 0 to
+  // total_test_case_count() - 1. If i is not in that range, returns NULL.
+  TestCase* GetMutableTestCase(int i);
+
+  // Accessors for the implementation object.
+  internal::UnitTestImpl* impl() { return impl_; }
+  const internal::UnitTestImpl* impl() const { return impl_; }
+
+  // These classes and funcions are friends as they need to access private
+  // members of UnitTest.
+  friend class Test;
+  friend class internal::AssertHelper;
+  friend class internal::ScopedTrace;
+  friend Environment* AddGlobalTestEnvironment(Environment* env);
+  friend internal::UnitTestImpl* internal::GetUnitTestImpl();
+  friend void internal::ReportFailureInUnknownLocation(
+      TestPartResult::Type result_type,
+      const internal::String& message);
+
+  // Creates an empty UnitTest.
+  UnitTest();
+
+  // D'tor
+  virtual ~UnitTest();
+
+  // Pushes a trace defined by SCOPED_TRACE() on to the per-thread
+  // Google Test trace stack.
+  void PushGTestTrace(const internal::TraceInfo& trace);
+
+  // Pops a trace from the per-thread Google Test trace stack.
+  void PopGTestTrace();
+
+  // Protects mutable state in *impl_.  This is mutable as some const
+  // methods need to lock it too.
+  mutable internal::Mutex mutex_;
+
+  // Opaque implementation object.  This field is never changed once
+  // the object is constructed.  We don't mark it as const here, as
+  // doing so will cause a warning in the constructor of UnitTest.
+  // Mutable state in *impl_ is protected by mutex_.
+  internal::UnitTestImpl* impl_;
+
+  // We disallow copying UnitTest.
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest);
+};
+
+// A convenient wrapper for adding an environment for the test
+// program.
+//
+// You should call this before RUN_ALL_TESTS() is called, probably in
+// main().  If you use gtest_main, you need to call this before main()
+// starts for it to take effect.  For example, you can define a global
+// variable like this:
+//
+//   testing::Environment* const foo_env =
+//       testing::AddGlobalTestEnvironment(new FooEnvironment);
+//
+// However, we strongly recommend you to write your own main() and
+// call AddGlobalTestEnvironment() there, as relying on initialization
+// of global variables makes the code harder to read and may cause
+// problems when you register multiple environments from different
+// translation units and the environments have dependencies among them
+// (remember that the compiler doesn't guarantee the order in which
+// global variables from different translation units are initialized).
+inline Environment* AddGlobalTestEnvironment(Environment* env) {
+  return UnitTest::GetInstance()->AddEnvironment(env);
+}
+
+// Initializes Google Test.  This must be called before calling
+// RUN_ALL_TESTS().  In particular, it parses a command line for the
+// flags that Google Test recognizes.  Whenever a Google Test flag is
+// seen, it is removed from argv, and *argc is decremented.
+//
+// No value is returned.  Instead, the Google Test flag variables are
+// updated.
+//
+// Calling the function for the second time has no user-visible effect.
+GTEST_API_ void InitGoogleTest(int* argc, char** argv);
+
+// This overloaded version can be used in Windows programs compiled in
+// UNICODE mode.
+GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv);
+
+namespace internal {
+
+// These overloaded versions handle ::std::string and ::std::wstring.
+GTEST_API_ inline String FormatForFailureMessage(const ::std::string& str) {
+  return (Message() << '"' << str << '"').GetString();
+}
+
+#if GTEST_HAS_STD_WSTRING
+GTEST_API_ inline String FormatForFailureMessage(const ::std::wstring& wstr) {
+  return (Message() << "L\"" << wstr << '"').GetString();
+}
+#endif  // GTEST_HAS_STD_WSTRING
+
+// These overloaded versions handle ::string and ::wstring.
+#if GTEST_HAS_GLOBAL_STRING
+GTEST_API_ inline String FormatForFailureMessage(const ::string& str) {
+  return (Message() << '"' << str << '"').GetString();
+}
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+#if GTEST_HAS_GLOBAL_WSTRING
+GTEST_API_ inline String FormatForFailureMessage(const ::wstring& wstr) {
+  return (Message() << "L\"" << wstr << '"').GetString();
+}
+#endif  // GTEST_HAS_GLOBAL_WSTRING
+
+// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc)
+// operand to be used in a failure message.  The type (but not value)
+// of the other operand may affect the format.  This allows us to
+// print a char* as a raw pointer when it is compared against another
+// char*, and print it as a C string when it is compared against an
+// std::string object, for example.
+//
+// The default implementation ignores the type of the other operand.
+// Some specialized versions are used to handle formatting wide or
+// narrow C strings.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+template <typename T1, typename T2>
+String FormatForComparisonFailureMessage(const T1& value,
+                                         const T2& /* other_operand */) {
+  return FormatForFailureMessage(value);
+}
+
+// The helper function for {ASSERT|EXPECT}_EQ.
+template <typename T1, typename T2>
+AssertionResult CmpHelperEQ(const char* expected_expression,
+                            const char* actual_expression,
+                            const T1& expected,
+                            const T2& actual) {
+#ifdef _MSC_VER
+#pragma warning(push)          // Saves the current warning state.
+#pragma warning(disable:4389)  // Temporarily disables warning on
+                               // signed/unsigned mismatch.
+#endif
+
+  if (expected == actual) {
+    return AssertionSuccess();
+  }
+
+#ifdef _MSC_VER
+#pragma warning(pop)          // Restores the warning state.
+#endif
+
+  return EqFailure(expected_expression,
+                   actual_expression,
+                   FormatForComparisonFailureMessage(expected, actual),
+                   FormatForComparisonFailureMessage(actual, expected),
+                   false);
+}
+
+// With this overloaded version, we allow anonymous enums to be used
+// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums
+// can be implicitly cast to BiggestInt.
+GTEST_API_ AssertionResult CmpHelperEQ(const char* expected_expression,
+                                       const char* actual_expression,
+                                       BiggestInt expected,
+                                       BiggestInt actual);
+
+// The helper class for {ASSERT|EXPECT}_EQ.  The template argument
+// lhs_is_null_literal is true iff the first argument to ASSERT_EQ()
+// is a null pointer literal.  The following default implementation is
+// for lhs_is_null_literal being false.
+template <bool lhs_is_null_literal>
+class EqHelper {
+ public:
+  // This templatized version is for the general case.
+  template <typename T1, typename T2>
+  static AssertionResult Compare(const char* expected_expression,
+                                 const char* actual_expression,
+                                 const T1& expected,
+                                 const T2& actual) {
+    return CmpHelperEQ(expected_expression, actual_expression, expected,
+                       actual);
+  }
+
+  // With this overloaded version, we allow anonymous enums to be used
+  // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous
+  // enums can be implicitly cast to BiggestInt.
+  //
+  // Even though its body looks the same as the above version, we
+  // cannot merge the two, as it will make anonymous enums unhappy.
+  static AssertionResult Compare(const char* expected_expression,
+                                 const char* actual_expression,
+                                 BiggestInt expected,
+                                 BiggestInt actual) {
+    return CmpHelperEQ(expected_expression, actual_expression, expected,
+                       actual);
+  }
+};
+
+// This specialization is used when the first argument to ASSERT_EQ()
+// is a null pointer literal.
+template <>
+class EqHelper<true> {
+ public:
+  // We define two overloaded versions of Compare().  The first
+  // version will be picked when the second argument to ASSERT_EQ() is
+  // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or
+  // EXPECT_EQ(false, a_bool).
+  template <typename T1, typename T2>
+  static AssertionResult Compare(const char* expected_expression,
+                                 const char* actual_expression,
+                                 const T1& expected,
+                                 const T2& actual) {
+    return CmpHelperEQ(expected_expression, actual_expression, expected,
+                       actual);
+  }
+
+  // This version will be picked when the second argument to
+  // ASSERT_EQ() is a pointer, e.g. ASSERT_EQ(NULL, a_pointer).
+  template <typename T1, typename T2>
+  static AssertionResult Compare(const char* expected_expression,
+                                 const char* actual_expression,
+                                 const T1& /* expected */,
+                                 T2* actual) {
+    // We already know that 'expected' is a null pointer.
+    return CmpHelperEQ(expected_expression, actual_expression,
+                       static_cast<T2*>(NULL), actual);
+  }
+};
+
+// A macro for implementing the helper functions needed to implement
+// ASSERT_?? and EXPECT_??.  It is here just to avoid copy-and-paste
+// of similar code.
+//
+// For each templatized helper function, we also define an overloaded
+// version for BiggestInt in order to reduce code bloat and allow
+// anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled
+// with gcc 4.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+#define GTEST_IMPL_CMP_HELPER_(op_name, op)\
+template <typename T1, typename T2>\
+AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \
+                                   const T1& val1, const T2& val2) {\
+  if (val1 op val2) {\
+    return AssertionSuccess();\
+  } else {\
+    Message msg;\
+    msg << "Expected: (" << expr1 << ") " #op " (" << expr2\
+        << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\
+        << " vs " << FormatForComparisonFailureMessage(val2, val1);\
+    return AssertionFailure(msg);\
+  }\
+}\
+GTEST_API_ AssertionResult CmpHelper##op_name(\
+    const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2)
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+
+// Implements the helper function for {ASSERT|EXPECT}_NE
+GTEST_IMPL_CMP_HELPER_(NE, !=);
+// Implements the helper function for {ASSERT|EXPECT}_LE
+GTEST_IMPL_CMP_HELPER_(LE, <=);
+// Implements the helper function for {ASSERT|EXPECT}_LT
+GTEST_IMPL_CMP_HELPER_(LT, < );
+// Implements the helper function for {ASSERT|EXPECT}_GE
+GTEST_IMPL_CMP_HELPER_(GE, >=);
+// Implements the helper function for {ASSERT|EXPECT}_GT
+GTEST_IMPL_CMP_HELPER_(GT, > );
+
+#undef GTEST_IMPL_CMP_HELPER_
+
+// The helper function for {ASSERT|EXPECT}_STREQ.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression,
+                                          const char* actual_expression,
+                                          const char* expected,
+                                          const char* actual);
+
+// The helper function for {ASSERT|EXPECT}_STRCASEEQ.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression,
+                                              const char* actual_expression,
+                                              const char* expected,
+                                              const char* actual);
+
+// The helper function for {ASSERT|EXPECT}_STRNE.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,
+                                          const char* s2_expression,
+                                          const char* s1,
+                                          const char* s2);
+
+// The helper function for {ASSERT|EXPECT}_STRCASENE.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
+                                              const char* s2_expression,
+                                              const char* s1,
+                                              const char* s2);
+
+
+// Helper function for *_STREQ on wide strings.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression,
+                                          const char* actual_expression,
+                                          const wchar_t* expected,
+                                          const wchar_t* actual);
+
+// Helper function for *_STRNE on wide strings.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,
+                                          const char* s2_expression,
+                                          const wchar_t* s1,
+                                          const wchar_t* s2);
+
+}  // namespace internal
+
+// IsSubstring() and IsNotSubstring() are intended to be used as the
+// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by
+// themselves.  They check whether needle is a substring of haystack
+// (NULL is considered a substring of itself only), and return an
+// appropriate error message when they fail.
+//
+// The {needle,haystack}_expr arguments are the stringified
+// expressions that generated the two real arguments.
+GTEST_API_ AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const char* needle, const char* haystack);
+GTEST_API_ AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const wchar_t* needle, const wchar_t* haystack);
+GTEST_API_ AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const char* needle, const char* haystack);
+GTEST_API_ AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const wchar_t* needle, const wchar_t* haystack);
+GTEST_API_ AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::string& needle, const ::std::string& haystack);
+GTEST_API_ AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::string& needle, const ::std::string& haystack);
+
+#if GTEST_HAS_STD_WSTRING
+GTEST_API_ AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::wstring& needle, const ::std::wstring& haystack);
+GTEST_API_ AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::wstring& needle, const ::std::wstring& haystack);
+#endif  // GTEST_HAS_STD_WSTRING
+
+namespace internal {
+
+// Helper template function for comparing floating-points.
+//
+// Template parameter:
+//
+//   RawType: the raw floating-point type (either float or double)
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+template <typename RawType>
+AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression,
+                                         const char* actual_expression,
+                                         RawType expected,
+                                         RawType actual) {
+  const FloatingPoint<RawType> lhs(expected), rhs(actual);
+
+  if (lhs.AlmostEquals(rhs)) {
+    return AssertionSuccess();
+  }
+
+  StrStream expected_ss;
+  expected_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
+              << expected;
+
+  StrStream actual_ss;
+  actual_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
+            << actual;
+
+  return EqFailure(expected_expression,
+                   actual_expression,
+                   StrStreamToString(&expected_ss),
+                   StrStreamToString(&actual_ss),
+                   false);
+}
+
+// Helper function for implementing ASSERT_NEAR.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1,
+                                                const char* expr2,
+                                                const char* abs_error_expr,
+                                                double val1,
+                                                double val2,
+                                                double abs_error);
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+// A class that enables one to stream messages to assertion macros
+class GTEST_API_ AssertHelper {
+ public:
+  // Constructor.
+  AssertHelper(TestPartResult::Type type,
+               const char* file,
+               int line,
+               const char* message);
+  ~AssertHelper();
+
+  // Message assignment is a semantic trick to enable assertion
+  // streaming; see the GTEST_MESSAGE_ macro below.
+  void operator=(const Message& message) const;
+
+ private:
+  // We put our data in a struct so that the size of the AssertHelper class can
+  // be as small as possible.  This is important because gcc is incapable of
+  // re-using stack space even for temporary variables, so every EXPECT_EQ
+  // reserves stack space for another AssertHelper.
+  struct AssertHelperData {
+    AssertHelperData(TestPartResult::Type t,
+                     const char* srcfile,
+                     int line_num,
+                     const char* msg)
+        : type(t), file(srcfile), line(line_num), message(msg) { }
+
+    TestPartResult::Type const type;
+    const char*        const file;
+    int                const line;
+    String             const message;
+
+   private:
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData);
+  };
+
+  AssertHelperData* const data_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper);
+};
+
+}  // namespace internal
+
+#if GTEST_HAS_PARAM_TEST
+// The abstract base class that all value-parameterized tests inherit from.
+//
+// This class adds support for accessing the test parameter value via
+// the GetParam() method.
+//
+// Use it with one of the parameter generator defining functions, like Range(),
+// Values(), ValuesIn(), Bool(), and Combine().
+//
+// class FooTest : public ::testing::TestWithParam<int> {
+//  protected:
+//   FooTest() {
+//     // Can use GetParam() here.
+//   }
+//   virtual ~FooTest() {
+//     // Can use GetParam() here.
+//   }
+//   virtual void SetUp() {
+//     // Can use GetParam() here.
+//   }
+//   virtual void TearDown {
+//     // Can use GetParam() here.
+//   }
+// };
+// TEST_P(FooTest, DoesBar) {
+//   // Can use GetParam() method here.
+//   Foo foo;
+//   ASSERT_TRUE(foo.DoesBar(GetParam()));
+// }
+// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));
+
+template <typename T>
+class TestWithParam : public Test {
+ public:
+  typedef T ParamType;
+
+  // The current parameter value. Is also available in the test fixture's
+  // constructor.
+  const ParamType& GetParam() const { return *parameter_; }
+
+ private:
+  // Sets parameter value. The caller is responsible for making sure the value
+  // remains alive and unchanged throughout the current test.
+  static void SetParam(const ParamType* parameter) {
+    parameter_ = parameter;
+  }
+
+  // Static value used for accessing parameter during a test lifetime.
+  static const ParamType* parameter_;
+
+  // TestClass must be a subclass of TestWithParam<T>.
+  template <class TestClass> friend class internal::ParameterizedTestFactory;
+};
+
+template <typename T>
+const T* TestWithParam<T>::parameter_ = NULL;
+
+#endif  // GTEST_HAS_PARAM_TEST
+
+// Macros for indicating success/failure in test code.
+
+// ADD_FAILURE unconditionally adds a failure to the current test.
+// SUCCEED generates a success - it doesn't automatically make the
+// current test successful, as a test is only successful when it has
+// no failure.
+//
+// EXPECT_* verifies that a certain condition is satisfied.  If not,
+// it behaves like ADD_FAILURE.  In particular:
+//
+//   EXPECT_TRUE  verifies that a Boolean condition is true.
+//   EXPECT_FALSE verifies that a Boolean condition is false.
+//
+// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except
+// that they will also abort the current function on failure.  People
+// usually want the fail-fast behavior of FAIL and ASSERT_*, but those
+// writing data-driven tests often find themselves using ADD_FAILURE
+// and EXPECT_* more.
+//
+// Examples:
+//
+//   EXPECT_TRUE(server.StatusIsOK());
+//   ASSERT_FALSE(server.HasPendingRequest(port))
+//       << "There are still pending requests " << "on port " << port;
+
+// Generates a nonfatal failure with a generic message.
+#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed")
+
+// Generates a fatal failure with a generic message.
+#define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed")
+
+// Define this macro to 1 to omit the definition of FAIL(), which is a
+// generic name and clashes with some other libraries.
+#if !GTEST_DONT_DEFINE_FAIL
+#define FAIL() GTEST_FAIL()
+#endif
+
+// Generates a success with a generic message.
+#define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded")
+
+// Define this macro to 1 to omit the definition of SUCCEED(), which
+// is a generic name and clashes with some other libraries.
+#if !GTEST_DONT_DEFINE_SUCCEED
+#define SUCCEED() GTEST_SUCCEED()
+#endif
+
+// Macros for testing exceptions.
+//
+//    * {ASSERT|EXPECT}_THROW(statement, expected_exception):
+//         Tests that the statement throws the expected exception.
+//    * {ASSERT|EXPECT}_NO_THROW(statement):
+//         Tests that the statement doesn't throw any exception.
+//    * {ASSERT|EXPECT}_ANY_THROW(statement):
+//         Tests that the statement throws an exception.
+
+#define EXPECT_THROW(statement, expected_exception) \
+  GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_NO_THROW(statement) \
+  GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_ANY_THROW(statement) \
+  GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_THROW(statement, expected_exception) \
+  GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_)
+#define ASSERT_NO_THROW(statement) \
+  GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_)
+#define ASSERT_ANY_THROW(statement) \
+  GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_)
+
+// Boolean assertions. Condition can be either a Boolean expression or an
+// AssertionResult. For more information on how to use AssertionResult with
+// these macros see comments on that class.
+#define EXPECT_TRUE(condition) \
+  GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \
+                      GTEST_NONFATAL_FAILURE_)
+#define EXPECT_FALSE(condition) \
+  GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
+                      GTEST_NONFATAL_FAILURE_)
+#define ASSERT_TRUE(condition) \
+  GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \
+                      GTEST_FATAL_FAILURE_)
+#define ASSERT_FALSE(condition) \
+  GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
+                      GTEST_FATAL_FAILURE_)
+
+// Includes the auto-generated header that implements a family of
+// generic predicate assertion macros.
+#include <gtest/gtest_pred_impl.h>
+
+// Macros for testing equalities and inequalities.
+//
+//    * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual
+//    * {ASSERT|EXPECT}_NE(v1, v2):           Tests that v1 != v2
+//    * {ASSERT|EXPECT}_LT(v1, v2):           Tests that v1 < v2
+//    * {ASSERT|EXPECT}_LE(v1, v2):           Tests that v1 <= v2
+//    * {ASSERT|EXPECT}_GT(v1, v2):           Tests that v1 > v2
+//    * {ASSERT|EXPECT}_GE(v1, v2):           Tests that v1 >= v2
+//
+// When they are not, Google Test prints both the tested expressions and
+// their actual values.  The values must be compatible built-in types,
+// or you will get a compiler error.  By "compatible" we mean that the
+// values can be compared by the respective operator.
+//
+// Note:
+//
+//   1. It is possible to make a user-defined type work with
+//   {ASSERT|EXPECT}_??(), but that requires overloading the
+//   comparison operators and is thus discouraged by the Google C++
+//   Usage Guide.  Therefore, you are advised to use the
+//   {ASSERT|EXPECT}_TRUE() macro to assert that two objects are
+//   equal.
+//
+//   2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on
+//   pointers (in particular, C strings).  Therefore, if you use it
+//   with two C strings, you are testing how their locations in memory
+//   are related, not how their content is related.  To compare two C
+//   strings by content, use {ASSERT|EXPECT}_STR*().
+//
+//   3. {ASSERT|EXPECT}_EQ(expected, actual) is preferred to
+//   {ASSERT|EXPECT}_TRUE(expected == actual), as the former tells you
+//   what the actual value is when it fails, and similarly for the
+//   other comparisons.
+//
+//   4. Do not depend on the order in which {ASSERT|EXPECT}_??()
+//   evaluate their arguments, which is undefined.
+//
+//   5. These macros evaluate their arguments exactly once.
+//
+// Examples:
+//
+//   EXPECT_NE(5, Foo());
+//   EXPECT_EQ(NULL, a_pointer);
+//   ASSERT_LT(i, array_size);
+//   ASSERT_GT(records.size(), 0) << "There is no record left.";
+
+#define EXPECT_EQ(expected, actual) \
+  EXPECT_PRED_FORMAT2(::testing::internal:: \
+                      EqHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, \
+                      expected, actual)
+#define EXPECT_NE(expected, actual) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual)
+#define EXPECT_LE(val1, val2) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2)
+#define EXPECT_LT(val1, val2) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2)
+#define EXPECT_GE(val1, val2) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2)
+#define EXPECT_GT(val1, val2) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)
+
+#define ASSERT_EQ(expected, actual) \
+  ASSERT_PRED_FORMAT2(::testing::internal:: \
+                      EqHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, \
+                      expected, actual)
+#define ASSERT_NE(val1, val2) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2)
+#define ASSERT_LE(val1, val2) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2)
+#define ASSERT_LT(val1, val2) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2)
+#define ASSERT_GE(val1, val2) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2)
+#define ASSERT_GT(val1, val2) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)
+
+// C String Comparisons.  All tests treat NULL and any non-NULL string
+// as different.  Two NULLs are equal.
+//
+//    * {ASSERT|EXPECT}_STREQ(s1, s2):     Tests that s1 == s2
+//    * {ASSERT|EXPECT}_STRNE(s1, s2):     Tests that s1 != s2
+//    * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case
+//    * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case
+//
+// For wide or narrow string objects, you can use the
+// {ASSERT|EXPECT}_??() macros.
+//
+// Don't depend on the order in which the arguments are evaluated,
+// which is undefined.
+//
+// These macros evaluate their arguments exactly once.
+
+#define EXPECT_STREQ(expected, actual) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual)
+#define EXPECT_STRNE(s1, s2) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)
+#define EXPECT_STRCASEEQ(expected, actual) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual)
+#define EXPECT_STRCASENE(s1, s2)\
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)
+
+#define ASSERT_STREQ(expected, actual) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual)
+#define ASSERT_STRNE(s1, s2) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)
+#define ASSERT_STRCASEEQ(expected, actual) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual)
+#define ASSERT_STRCASENE(s1, s2)\
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)
+
+// Macros for comparing floating-point numbers.
+//
+//    * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual):
+//         Tests that two float values are almost equal.
+//    * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual):
+//         Tests that two double values are almost equal.
+//    * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error):
+//         Tests that v1 and v2 are within the given distance to each other.
+//
+// Google Test uses ULP-based comparison to automatically pick a default
+// error bound that is appropriate for the operands.  See the
+// FloatingPoint template class in gtest-internal.h if you are
+// interested in the implementation details.
+
+#define EXPECT_FLOAT_EQ(expected, actual)\
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \
+                      expected, actual)
+
+#define EXPECT_DOUBLE_EQ(expected, actual)\
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \
+                      expected, actual)
+
+#define ASSERT_FLOAT_EQ(expected, actual)\
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \
+                      expected, actual)
+
+#define ASSERT_DOUBLE_EQ(expected, actual)\
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \
+                      expected, actual)
+
+#define EXPECT_NEAR(val1, val2, abs_error)\
+  EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \
+                      val1, val2, abs_error)
+
+#define ASSERT_NEAR(val1, val2, abs_error)\
+  ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \
+                      val1, val2, abs_error)
+
+// These predicate format functions work on floating-point values, and
+// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g.
+//
+//   EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0);
+
+// Asserts that val1 is less than, or almost equal to, val2.  Fails
+// otherwise.  In particular, it fails if either val1 or val2 is NaN.
+GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2,
+                                   float val1, float val2);
+GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,
+                                    double val1, double val2);
+
+
+#if GTEST_OS_WINDOWS
+
+// Macros that test for HRESULT failure and success, these are only useful
+// on Windows, and rely on Windows SDK macros and APIs to compile.
+//
+//    * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr)
+//
+// When expr unexpectedly fails or succeeds, Google Test prints the
+// expected result and the actual result with both a human-readable
+// string representation of the error, if available, as well as the
+// hex result code.
+#define EXPECT_HRESULT_SUCCEEDED(expr) \
+    EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))
+
+#define ASSERT_HRESULT_SUCCEEDED(expr) \
+    ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))
+
+#define EXPECT_HRESULT_FAILED(expr) \
+    EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))
+
+#define ASSERT_HRESULT_FAILED(expr) \
+    ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))
+
+#endif  // GTEST_OS_WINDOWS
+
+// Macros that execute statement and check that it doesn't generate new fatal
+// failures in the current thread.
+//
+//   * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement);
+//
+// Examples:
+//
+//   EXPECT_NO_FATAL_FAILURE(Process());
+//   ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed";
+//
+#define ASSERT_NO_FATAL_FAILURE(statement) \
+    GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_)
+#define EXPECT_NO_FATAL_FAILURE(statement) \
+    GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_)
+
+// Causes a trace (including the source file path, the current line
+// number, and the given message) to be included in every test failure
+// message generated by code in the current scope.  The effect is
+// undone when the control leaves the current scope.
+//
+// The message argument can be anything streamable to std::ostream.
+//
+// In the implementation, we include the current line number as part
+// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s
+// to appear in the same block - as long as they are on different
+// lines.
+#define SCOPED_TRACE(message) \
+  ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\
+    __FILE__, __LINE__, ::testing::Message() << (message))
+
+namespace internal {
+
+// This template is declared, but intentionally undefined.
+template <typename T1, typename T2>
+struct StaticAssertTypeEqHelper;
+
+template <typename T>
+struct StaticAssertTypeEqHelper<T, T> {};
+
+}  // namespace internal
+
+// Compile-time assertion for type equality.
+// StaticAssertTypeEq<type1, type2>() compiles iff type1 and type2 are
+// the same type.  The value it returns is not interesting.
+//
+// Instead of making StaticAssertTypeEq a class template, we make it a
+// function template that invokes a helper class template.  This
+// prevents a user from misusing StaticAssertTypeEq<T1, T2> by
+// defining objects of that type.
+//
+// CAVEAT:
+//
+// When used inside a method of a class template,
+// StaticAssertTypeEq<T1, T2>() is effective ONLY IF the method is
+// instantiated.  For example, given:
+//
+//   template <typename T> class Foo {
+//    public:
+//     void Bar() { testing::StaticAssertTypeEq<int, T>(); }
+//   };
+//
+// the code:
+//
+//   void Test1() { Foo<bool> foo; }
+//
+// will NOT generate a compiler error, as Foo<bool>::Bar() is never
+// actually instantiated.  Instead, you need:
+//
+//   void Test2() { Foo<bool> foo; foo.Bar(); }
+//
+// to cause a compiler error.
+template <typename T1, typename T2>
+bool StaticAssertTypeEq() {
+  internal::StaticAssertTypeEqHelper<T1, T2>();
+  return true;
+}
+
+// Defines a test.
+//
+// The first parameter is the name of the test case, and the second
+// parameter is the name of the test within the test case.
+//
+// The convention is to end the test case name with "Test".  For
+// example, a test case for the Foo class can be named FooTest.
+//
+// The user should put his test code between braces after using this
+// macro.  Example:
+//
+//   TEST(FooTest, InitializesCorrectly) {
+//     Foo foo;
+//     EXPECT_TRUE(foo.StatusIsOK());
+//   }
+
+// Note that we call GetTestTypeId() instead of GetTypeId<
+// ::testing::Test>() here to get the type ID of testing::Test.  This
+// is to work around a suspected linker bug when using Google Test as
+// a framework on Mac OS X.  The bug causes GetTypeId<
+// ::testing::Test>() to return different values depending on whether
+// the call is from the Google Test framework itself or from user test
+// code.  GetTestTypeId() is guaranteed to always return the same
+// value, as it always calls GetTypeId<>() from the Google Test
+// framework.
+#define GTEST_TEST(test_case_name, test_name)\
+  GTEST_TEST_(test_case_name, test_name, \
+              ::testing::Test, ::testing::internal::GetTestTypeId())
+
+// Define this macro to 1 to omit the definition of TEST(), which
+// is a generic name and clashes with some other libraries.
+#if !GTEST_DONT_DEFINE_TEST
+#define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name)
+#endif
+
+// Defines a test that uses a test fixture.
+//
+// The first parameter is the name of the test fixture class, which
+// also doubles as the test case name.  The second parameter is the
+// name of the test within the test case.
+//
+// A test fixture class must be declared earlier.  The user should put
+// his test code between braces after using this macro.  Example:
+//
+//   class FooTest : public testing::Test {
+//    protected:
+//     virtual void SetUp() { b_.AddElement(3); }
+//
+//     Foo a_;
+//     Foo b_;
+//   };
+//
+//   TEST_F(FooTest, InitializesCorrectly) {
+//     EXPECT_TRUE(a_.StatusIsOK());
+//   }
+//
+//   TEST_F(FooTest, ReturnsElementCountCorrectly) {
+//     EXPECT_EQ(0, a_.size());
+//     EXPECT_EQ(1, b_.size());
+//   }
+
+#define TEST_F(test_fixture, test_name)\
+  GTEST_TEST_(test_fixture, test_name, test_fixture, \
+              ::testing::internal::GetTypeId<test_fixture>())
+
+// Use this macro in main() to run all tests.  It returns 0 if all
+// tests are successful, or 1 otherwise.
+//
+// RUN_ALL_TESTS() should be invoked after the command line has been
+// parsed by InitGoogleTest().
+
+#define RUN_ALL_TESTS()\
+  (::testing::UnitTest::GetInstance()->Run())
+
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_H_
diff --git a/src/LLVM/utils/unittest/googletest/include/gtest/gtest_pred_impl.h b/src/LLVM/utils/unittest/googletest/include/gtest/gtest_pred_impl.h
new file mode 100644
index 0000000..e1e2f8c
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/include/gtest/gtest_pred_impl.h
@@ -0,0 +1,368 @@
+// Copyright 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is AUTOMATICALLY GENERATED on 10/02/2008 by command
+// 'gen_gtest_pred_impl.py 5'.  DO NOT EDIT BY HAND!
+//
+// Implements a family of generic predicate assertion macros.
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
+#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
+
+// Makes sure this header is not included before gtest.h.
+#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
+#error Do not include gtest_pred_impl.h directly.  Include gtest.h instead.
+#endif  // GTEST_INCLUDE_GTEST_GTEST_H_
+
+// This header implements a family of generic predicate assertion
+// macros:
+//
+//   ASSERT_PRED_FORMAT1(pred_format, v1)
+//   ASSERT_PRED_FORMAT2(pred_format, v1, v2)
+//   ...
+//
+// where pred_format is a function or functor that takes n (in the
+// case of ASSERT_PRED_FORMATn) values and their source expression
+// text, and returns a testing::AssertionResult.  See the definition
+// of ASSERT_EQ in gtest.h for an example.
+//
+// If you don't care about formatting, you can use the more
+// restrictive version:
+//
+//   ASSERT_PRED1(pred, v1)
+//   ASSERT_PRED2(pred, v1, v2)
+//   ...
+//
+// where pred is an n-ary function or functor that returns bool,
+// and the values v1, v2, ..., must support the << operator for
+// streaming to std::ostream.
+//
+// We also define the EXPECT_* variations.
+//
+// For now we only support predicates whose arity is at most 5.
+// Please email googletestframework@googlegroups.com if you need
+// support for higher arities.
+
+// GTEST_ASSERT_ is the basic statement to which all of the assertions
+// in this file reduce.  Don't use this in your code.
+
+#define GTEST_ASSERT_(expression, on_failure) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (const ::testing::AssertionResult gtest_ar = (expression)) \
+    ; \
+  else \
+    on_failure(gtest_ar.failure_message())
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED1.  Don't use
+// this in your code.
+template <typename Pred,
+          typename T1>
+AssertionResult AssertPred1Helper(const char* pred_text,
+                                  const char* e1,
+                                  Pred pred,
+                                  const T1& v1) {
+  if (pred(v1)) return AssertionSuccess();
+
+  Message msg;
+  msg << pred_text << "("
+      << e1 << ") evaluates to false, where"
+      << "\n" << e1 << " evaluates to " << v1;
+  return AssertionFailure(msg);
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\
+  GTEST_ASSERT_(pred_format(#v1, v1),\
+                on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED1.  Don't use
+// this in your code.
+#define GTEST_PRED1_(pred, v1, on_failure)\
+  GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \
+                                             #v1, \
+                                             pred, \
+                                             v1), on_failure)
+
+// Unary predicate assertion macros.
+#define EXPECT_PRED_FORMAT1(pred_format, v1) \
+  GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_PRED1(pred, v1) \
+  GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_PRED_FORMAT1(pred_format, v1) \
+  GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)
+#define ASSERT_PRED1(pred, v1) \
+  GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)
+
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED2.  Don't use
+// this in your code.
+template <typename Pred,
+          typename T1,
+          typename T2>
+AssertionResult AssertPred2Helper(const char* pred_text,
+                                  const char* e1,
+                                  const char* e2,
+                                  Pred pred,
+                                  const T1& v1,
+                                  const T2& v2) {
+  if (pred(v1, v2)) return AssertionSuccess();
+
+  Message msg;
+  msg << pred_text << "("
+      << e1 << ", "
+      << e2 << ") evaluates to false, where"
+      << "\n" << e1 << " evaluates to " << v1
+      << "\n" << e2 << " evaluates to " << v2;
+  return AssertionFailure(msg);
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\
+  GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2),\
+                on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED2.  Don't use
+// this in your code.
+#define GTEST_PRED2_(pred, v1, v2, on_failure)\
+  GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \
+                                             #v1, \
+                                             #v2, \
+                                             pred, \
+                                             v1, \
+                                             v2), on_failure)
+
+// Binary predicate assertion macros.
+#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \
+  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_PRED2(pred, v1, v2) \
+  GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \
+  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_)
+#define ASSERT_PRED2(pred, v1, v2) \
+  GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_)
+
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED3.  Don't use
+// this in your code.
+template <typename Pred,
+          typename T1,
+          typename T2,
+          typename T3>
+AssertionResult AssertPred3Helper(const char* pred_text,
+                                  const char* e1,
+                                  const char* e2,
+                                  const char* e3,
+                                  Pred pred,
+                                  const T1& v1,
+                                  const T2& v2,
+                                  const T3& v3) {
+  if (pred(v1, v2, v3)) return AssertionSuccess();
+
+  Message msg;
+  msg << pred_text << "("
+      << e1 << ", "
+      << e2 << ", "
+      << e3 << ") evaluates to false, where"
+      << "\n" << e1 << " evaluates to " << v1
+      << "\n" << e2 << " evaluates to " << v2
+      << "\n" << e3 << " evaluates to " << v3;
+  return AssertionFailure(msg);
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\
+  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3),\
+                on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED3.  Don't use
+// this in your code.
+#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\
+  GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \
+                                             #v1, \
+                                             #v2, \
+                                             #v3, \
+                                             pred, \
+                                             v1, \
+                                             v2, \
+                                             v3), on_failure)
+
+// Ternary predicate assertion macros.
+#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \
+  GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_PRED3(pred, v1, v2, v3) \
+  GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \
+  GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_)
+#define ASSERT_PRED3(pred, v1, v2, v3) \
+  GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_)
+
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED4.  Don't use
+// this in your code.
+template <typename Pred,
+          typename T1,
+          typename T2,
+          typename T3,
+          typename T4>
+AssertionResult AssertPred4Helper(const char* pred_text,
+                                  const char* e1,
+                                  const char* e2,
+                                  const char* e3,
+                                  const char* e4,
+                                  Pred pred,
+                                  const T1& v1,
+                                  const T2& v2,
+                                  const T3& v3,
+                                  const T4& v4) {
+  if (pred(v1, v2, v3, v4)) return AssertionSuccess();
+
+  Message msg;
+  msg << pred_text << "("
+      << e1 << ", "
+      << e2 << ", "
+      << e3 << ", "
+      << e4 << ") evaluates to false, where"
+      << "\n" << e1 << " evaluates to " << v1
+      << "\n" << e2 << " evaluates to " << v2
+      << "\n" << e3 << " evaluates to " << v3
+      << "\n" << e4 << " evaluates to " << v4;
+  return AssertionFailure(msg);
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\
+  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4),\
+                on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED4.  Don't use
+// this in your code.
+#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\
+  GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \
+                                             #v1, \
+                                             #v2, \
+                                             #v3, \
+                                             #v4, \
+                                             pred, \
+                                             v1, \
+                                             v2, \
+                                             v3, \
+                                             v4), on_failure)
+
+// 4-ary predicate assertion macros.
+#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
+  GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_PRED4(pred, v1, v2, v3, v4) \
+  GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
+  GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
+#define ASSERT_PRED4(pred, v1, v2, v3, v4) \
+  GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
+
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED5.  Don't use
+// this in your code.
+template <typename Pred,
+          typename T1,
+          typename T2,
+          typename T3,
+          typename T4,
+          typename T5>
+AssertionResult AssertPred5Helper(const char* pred_text,
+                                  const char* e1,
+                                  const char* e2,
+                                  const char* e3,
+                                  const char* e4,
+                                  const char* e5,
+                                  Pred pred,
+                                  const T1& v1,
+                                  const T2& v2,
+                                  const T3& v3,
+                                  const T4& v4,
+                                  const T5& v5) {
+  if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();
+
+  Message msg;
+  msg << pred_text << "("
+      << e1 << ", "
+      << e2 << ", "
+      << e3 << ", "
+      << e4 << ", "
+      << e5 << ") evaluates to false, where"
+      << "\n" << e1 << " evaluates to " << v1
+      << "\n" << e2 << " evaluates to " << v2
+      << "\n" << e3 << " evaluates to " << v3
+      << "\n" << e4 << " evaluates to " << v4
+      << "\n" << e5 << " evaluates to " << v5;
+  return AssertionFailure(msg);
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\
+  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5),\
+                on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED5.  Don't use
+// this in your code.
+#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\
+  GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \
+                                             #v1, \
+                                             #v2, \
+                                             #v3, \
+                                             #v4, \
+                                             #v5, \
+                                             pred, \
+                                             v1, \
+                                             v2, \
+                                             v3, \
+                                             v4, \
+                                             v5), on_failure)
+
+// 5-ary predicate assertion macros.
+#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
+  GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \
+  GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
+  GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
+#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \
+  GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
+
+
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
diff --git a/src/LLVM/utils/unittest/googletest/include/gtest/gtest_prod.h b/src/LLVM/utils/unittest/googletest/include/gtest/gtest_prod.h
new file mode 100644
index 0000000..da80ddc
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/include/gtest/gtest_prod.h
@@ -0,0 +1,58 @@
+// Copyright 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// Google C++ Testing Framework definitions useful in production code.
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_
+#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_
+
+// When you need to test the private or protected members of a class,
+// use the FRIEND_TEST macro to declare your tests as friends of the
+// class.  For example:
+//
+// class MyClass {
+//  private:
+//   void MyMethod();
+//   FRIEND_TEST(MyClassTest, MyMethod);
+// };
+//
+// class MyClassTest : public testing::Test {
+//   // ...
+// };
+//
+// TEST_F(MyClassTest, MyMethod) {
+//   // Can call MyClass::MyMethod() here.
+// }
+
+#define FRIEND_TEST(test_case_name, test_name)\
+friend class test_case_name##_##test_name##_Test
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_PROD_H_
diff --git a/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h
new file mode 100644
index 0000000..e433084
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h
@@ -0,0 +1,275 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file defines internal utilities needed for implementing
+// death tests.  They are subject to change without notice.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
+
+#include <gtest/internal/gtest-internal.h>
+
+namespace testing {
+namespace internal {
+
+GTEST_DECLARE_string_(internal_run_death_test);
+
+// Names of the flags (needed for parsing Google Test flags).
+const char kDeathTestStyleFlag[] = "death_test_style";
+const char kDeathTestUseFork[] = "death_test_use_fork";
+const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
+
+#if GTEST_HAS_DEATH_TEST
+
+// DeathTest is a class that hides much of the complexity of the
+// GTEST_DEATH_TEST_ macro.  It is abstract; its static Create method
+// returns a concrete class that depends on the prevailing death test
+// style, as defined by the --gtest_death_test_style and/or
+// --gtest_internal_run_death_test flags.
+
+// In describing the results of death tests, these terms are used with
+// the corresponding definitions:
+//
+// exit status:  The integer exit information in the format specified
+//               by wait(2)
+// exit code:    The integer code passed to exit(3), _exit(2), or
+//               returned from main()
+class GTEST_API_ DeathTest {
+ public:
+  // Create returns false if there was an error determining the
+  // appropriate action to take for the current death test; for example,
+  // if the gtest_death_test_style flag is set to an invalid value.
+  // The LastMessage method will return a more detailed message in that
+  // case.  Otherwise, the DeathTest pointer pointed to by the "test"
+  // argument is set.  If the death test should be skipped, the pointer
+  // is set to NULL; otherwise, it is set to the address of a new concrete
+  // DeathTest object that controls the execution of the current test.
+  static bool Create(const char* statement, const RE* regex,
+                     const char* file, int line, DeathTest** test);
+  DeathTest();
+  virtual ~DeathTest() { }
+
+  // A helper class that aborts a death test when it's deleted.
+  class ReturnSentinel {
+   public:
+    explicit ReturnSentinel(DeathTest* test) : test_(test) { }
+    ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }
+   private:
+    DeathTest* const test_;
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel);
+  } GTEST_ATTRIBUTE_UNUSED_;
+
+  // An enumeration of possible roles that may be taken when a death
+  // test is encountered.  EXECUTE means that the death test logic should
+  // be executed immediately.  OVERSEE means that the program should prepare
+  // the appropriate environment for a child process to execute the death
+  // test, then wait for it to complete.
+  enum TestRole { OVERSEE_TEST, EXECUTE_TEST };
+
+  // An enumeration of the two reasons that a test might be aborted.
+  enum AbortReason { TEST_ENCOUNTERED_RETURN_STATEMENT, TEST_DID_NOT_DIE };
+
+  // Assumes one of the above roles.
+  virtual TestRole AssumeRole() = 0;
+
+  // Waits for the death test to finish and returns its status.
+  virtual int Wait() = 0;
+
+  // Returns true if the death test passed; that is, the test process
+  // exited during the test, its exit status matches a user-supplied
+  // predicate, and its stderr output matches a user-supplied regular
+  // expression.
+  // The user-supplied predicate may be a macro expression rather
+  // than a function pointer or functor, or else Wait and Passed could
+  // be combined.
+  virtual bool Passed(bool exit_status_ok) = 0;
+
+  // Signals that the death test did not die as expected.
+  virtual void Abort(AbortReason reason) = 0;
+
+  // Returns a human-readable outcome message regarding the outcome of
+  // the last death test.
+  static const char* LastMessage();
+
+  static void set_last_death_test_message(const String& message);
+
+ private:
+  // A string containing a description of the outcome of the last death test.
+  static String last_death_test_message_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest);
+};
+
+// Factory interface for death tests.  May be mocked out for testing.
+class DeathTestFactory {
+ public:
+  virtual ~DeathTestFactory() { }
+  virtual bool Create(const char* statement, const RE* regex,
+                      const char* file, int line, DeathTest** test) = 0;
+};
+
+// A concrete DeathTestFactory implementation for normal use.
+class DefaultDeathTestFactory : public DeathTestFactory {
+ public:
+  virtual bool Create(const char* statement, const RE* regex,
+                      const char* file, int line, DeathTest** test);
+};
+
+// Returns true if exit_status describes a process that was terminated
+// by a signal, or exited normally with a nonzero exit code.
+GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
+
+// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
+// ASSERT_EXIT*, and EXPECT_EXIT*.
+#define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (::testing::internal::AlwaysTrue()) { \
+    const ::testing::internal::RE& gtest_regex = (regex); \
+    ::testing::internal::DeathTest* gtest_dt; \
+    if (!::testing::internal::DeathTest::Create(#statement, &gtest_regex, \
+        __FILE__, __LINE__, &gtest_dt)) { \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
+    } \
+    if (gtest_dt != NULL) { \
+      ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \
+          gtest_dt_ptr(gtest_dt); \
+      switch (gtest_dt->AssumeRole()) { \
+        case ::testing::internal::DeathTest::OVERSEE_TEST: \
+          if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
+            goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
+          } \
+          break; \
+        case ::testing::internal::DeathTest::EXECUTE_TEST: { \
+          ::testing::internal::DeathTest::ReturnSentinel \
+              gtest_sentinel(gtest_dt); \
+          GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+          gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
+          break; \
+        } \
+      } \
+    } \
+  } else \
+    GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \
+      fail(::testing::internal::DeathTest::LastMessage())
+// The symbol "fail" here expands to something into which a message
+// can be streamed.
+
+// A class representing the parsed contents of the
+// --gtest_internal_run_death_test flag, as it existed when
+// RUN_ALL_TESTS was called.
+class InternalRunDeathTestFlag {
+ public:
+  InternalRunDeathTestFlag(const String& a_file,
+                           int a_line,
+                           int an_index,
+                           int a_write_fd)
+      : file_(a_file), line_(a_line), index_(an_index),
+        write_fd_(a_write_fd) {}
+
+  ~InternalRunDeathTestFlag() {
+    if (write_fd_ >= 0)
+      posix::Close(write_fd_);
+  }
+
+  String file() const { return file_; }
+  int line() const { return line_; }
+  int index() const { return index_; }
+  int write_fd() const { return write_fd_; }
+
+ private:
+  String file_;
+  int line_;
+  int index_;
+  int write_fd_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag);
+};
+
+// Returns a newly created InternalRunDeathTestFlag object with fields
+// initialized from the GTEST_FLAG(internal_run_death_test) flag if
+// the flag is specified; otherwise returns NULL.
+InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
+
+#else  // GTEST_HAS_DEATH_TEST
+
+// This macro is used for implementing macros such as
+// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
+// death tests are not supported. Those macros must compile on such systems
+// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on
+// systems that support death tests. This allows one to write such a macro
+// on a system that does not support death tests and be sure that it will
+// compile on a death-test supporting system.
+//
+// Parameters:
+//   statement -  A statement that a macro such as EXPECT_DEATH would test
+//                for program termination. This macro has to make sure this
+//                statement is compiled but not executed, to ensure that
+//                EXPECT_DEATH_IF_SUPPORTED compiles with a certain
+//                parameter iff EXPECT_DEATH compiles with it.
+//   regex     -  A regex that a macro such as EXPECT_DEATH would use to test
+//                the output of statement.  This parameter has to be
+//                compiled but not evaluated by this macro, to ensure that
+//                this macro only accepts expressions that a macro such as
+//                EXPECT_DEATH would accept.
+//   terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED
+//                and a return statement for ASSERT_DEATH_IF_SUPPORTED.
+//                This ensures that ASSERT_DEATH_IF_SUPPORTED will not
+//                compile inside functions where ASSERT_DEATH doesn't
+//                compile.
+//
+//  The branch that has an always false condition is used to ensure that
+//  statement and regex are compiled (and thus syntactically correct) but
+//  never executed. The unreachable code macro protects the terminator
+//  statement from generating an 'unreachable code' warning in case
+//  statement unconditionally returns or throws. The Message constructor at
+//  the end allows the syntax of streaming additional messages into the
+//  macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
+#define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \
+    GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+    if (::testing::internal::AlwaysTrue()) { \
+      GTEST_LOG_(WARNING) \
+          << "Death tests are not supported on this platform.\n" \
+          << "Statement '" #statement "' cannot be verified."; \
+    } else if (::testing::internal::AlwaysFalse()) { \
+      ::testing::internal::RE::PartialMatch(".*", (regex)); \
+      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+      terminator; \
+    } else \
+      ::testing::Message()
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
diff --git a/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h
new file mode 100644
index 0000000..4b76d79
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h
@@ -0,0 +1,210 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: keith.ray@gmail.com (Keith Ray)
+//
+// Google Test filepath utilities
+//
+// This header file declares classes and functions used internally by
+// Google Test.  They are subject to change without notice.
+//
+// This file is #included in <gtest/internal/gtest-internal.h>.
+// Do not include this header file separately!
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
+
+#include <gtest/internal/gtest-string.h>
+
+namespace testing {
+namespace internal {
+
+// FilePath - a class for file and directory pathname manipulation which
+// handles platform-specific conventions (like the pathname separator).
+// Used for helper functions for naming files in a directory for xml output.
+// Except for Set methods, all methods are const or static, which provides an
+// "immutable value object" -- useful for peace of mind.
+// A FilePath with a value ending in a path separator ("like/this/") represents
+// a directory, otherwise it is assumed to represent a file. In either case,
+// it may or may not represent an actual file or directory in the file system.
+// Names are NOT checked for syntax correctness -- no checking for illegal
+// characters, malformed paths, etc.
+
+class GTEST_API_ FilePath {
+ public:
+  FilePath() : pathname_("") { }
+  FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { }
+
+  explicit FilePath(const char* pathname) : pathname_(pathname) {
+    Normalize();
+  }
+
+  explicit FilePath(const String& pathname) : pathname_(pathname) {
+    Normalize();
+  }
+
+  FilePath& operator=(const FilePath& rhs) {
+    Set(rhs);
+    return *this;
+  }
+
+  void Set(const FilePath& rhs) {
+    pathname_ = rhs.pathname_;
+  }
+
+  String ToString() const { return pathname_; }
+  const char* c_str() const { return pathname_.c_str(); }
+
+  // Returns the current working directory, or "" if unsuccessful.
+  static FilePath GetCurrentDir();
+
+  // Given directory = "dir", base_name = "test", number = 0,
+  // extension = "xml", returns "dir/test.xml". If number is greater
+  // than zero (e.g., 12), returns "dir/test_12.xml".
+  // On Windows platform, uses \ as the separator rather than /.
+  static FilePath MakeFileName(const FilePath& directory,
+                               const FilePath& base_name,
+                               int number,
+                               const char* extension);
+
+  // Given directory = "dir", relative_path = "test.xml",
+  // returns "dir/test.xml".
+  // On Windows, uses \ as the separator rather than /.
+  static FilePath ConcatPaths(const FilePath& directory,
+                              const FilePath& relative_path);
+
+  // Returns a pathname for a file that does not currently exist. The pathname
+  // will be directory/base_name.extension or
+  // directory/base_name_<number>.extension if directory/base_name.extension
+  // already exists. The number will be incremented until a pathname is found
+  // that does not already exist.
+  // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
+  // There could be a race condition if two or more processes are calling this
+  // function at the same time -- they could both pick the same filename.
+  static FilePath GenerateUniqueFileName(const FilePath& directory,
+                                         const FilePath& base_name,
+                                         const char* extension);
+
+  // Returns true iff the path is NULL or "".
+  bool IsEmpty() const { return c_str() == NULL || *c_str() == '\0'; }
+
+  // If input name has a trailing separator character, removes it and returns
+  // the name, otherwise return the name string unmodified.
+  // On Windows platform, uses \ as the separator, other platforms use /.
+  FilePath RemoveTrailingPathSeparator() const;
+
+  // Returns a copy of the FilePath with the directory part removed.
+  // Example: FilePath("path/to/file").RemoveDirectoryName() returns
+  // FilePath("file"). If there is no directory part ("just_a_file"), it returns
+  // the FilePath unmodified. If there is no file part ("just_a_dir/") it
+  // returns an empty FilePath ("").
+  // On Windows platform, '\' is the path separator, otherwise it is '/'.
+  FilePath RemoveDirectoryName() const;
+
+  // RemoveFileName returns the directory path with the filename removed.
+  // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
+  // If the FilePath is "a_file" or "/a_file", RemoveFileName returns
+  // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
+  // not have a file, like "just/a/dir/", it returns the FilePath unmodified.
+  // On Windows platform, '\' is the path separator, otherwise it is '/'.
+  FilePath RemoveFileName() const;
+
+  // Returns a copy of the FilePath with the case-insensitive extension removed.
+  // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
+  // FilePath("dir/file"). If a case-insensitive extension is not
+  // found, returns a copy of the original FilePath.
+  FilePath RemoveExtension(const char* extension) const;
+
+  // Creates directories so that path exists. Returns true if successful or if
+  // the directories already exist; returns false if unable to create
+  // directories for any reason. Will also return false if the FilePath does
+  // not represent a directory (that is, it doesn't end with a path separator).
+  bool CreateDirectoriesRecursively() const;
+
+  // Create the directory so that path exists. Returns true if successful or
+  // if the directory already exists; returns false if unable to create the
+  // directory for any reason, including if the parent directory does not
+  // exist. Not named "CreateDirectory" because that's a macro on Windows.
+  bool CreateFolder() const;
+
+  // Returns true if FilePath describes something in the file-system,
+  // either a file, directory, or whatever, and that something exists.
+  bool FileOrDirectoryExists() const;
+
+  // Returns true if pathname describes a directory in the file-system
+  // that exists.
+  bool DirectoryExists() const;
+
+  // Returns true if FilePath ends with a path separator, which indicates that
+  // it is intended to represent a directory. Returns false otherwise.
+  // This does NOT check that a directory (or file) actually exists.
+  bool IsDirectory() const;
+
+  // Returns true if pathname describes a root directory. (Windows has one
+  // root directory per disk drive.)
+  bool IsRootDirectory() const;
+
+  // Returns true if pathname describes an absolute path.
+  bool IsAbsolutePath() const;
+
+ private:
+  // Replaces multiple consecutive separators with a single separator.
+  // For example, "bar///foo" becomes "bar/foo". Does not eliminate other
+  // redundancies that might be in a pathname involving "." or "..".
+  //
+  // A pathname with multiple consecutive separators may occur either through
+  // user error or as a result of some scripts or APIs that generate a pathname
+  // with a trailing separator. On other platforms the same API or script
+  // may NOT generate a pathname with a trailing "/". Then elsewhere that
+  // pathname may have another "/" and pathname components added to it,
+  // without checking for the separator already being there.
+  // The script language and operating system may allow paths like "foo//bar"
+  // but some of the functions in FilePath will not handle that correctly. In
+  // particular, RemoveTrailingPathSeparator() only removes one separator, and
+  // it is called in CreateDirectoriesRecursively() assuming that it will change
+  // a pathname from directory syntax (trailing separator) to filename syntax.
+  //
+  // On Windows this method also replaces the alternate path separator '/' with
+  // the primary path separator '\\', so that for example "bar\\/\\foo" becomes
+  // "bar\\foo".
+
+  void Normalize();
+
+  // Returns a pointer to the last occurence of a valid path separator in
+  // the FilePath. On Windows, for example, both '/' and '\' are valid path
+  // separators. Returns NULL if no path separator was found.
+  const char* FindLastPathSeparator() const;
+
+  String pathname_;
+};  // class FilePath
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
diff --git a/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h
new file mode 100644
index 0000000..855b215
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h
@@ -0,0 +1,1074 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Utility functions and classes used by the Google C++ testing framework.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// This file contains purely Google Test's internal implementation.  Please
+// DO NOT #INCLUDE IT IN A USER PROGRAM.
+
+#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_
+#define GTEST_SRC_GTEST_INTERNAL_INL_H_
+
+// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is
+// part of Google Test's implementation; otherwise it's undefined.
+#if !GTEST_IMPLEMENTATION_
+// A user is trying to include this from his code - just say no.
+#error "gtest-internal-inl.h is part of Google Test's internal implementation."
+#error "It must not be included except by Google Test itself."
+#endif  // GTEST_IMPLEMENTATION_
+
+#ifndef _WIN32_WCE
+#include <errno.h>
+#endif  // !_WIN32_WCE
+#include <stddef.h>
+#include <stdlib.h>  // For strtoll/_strtoul64/malloc/free.
+#include <string.h>  // For memmove.
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include <gtest/internal/gtest-port.h>
+
+#if GTEST_OS_WINDOWS
+#include <windows.h>  // For DWORD.
+#endif  // GTEST_OS_WINDOWS
+
+#include <gtest/gtest.h>  // NOLINT
+#include <gtest/gtest-spi.h>
+
+namespace testing {
+
+// Declares the flags.
+//
+// We don't want the users to modify this flag in the code, but want
+// Google Test's own unit tests to be able to access it. Therefore we
+// declare it here as opposed to in gtest.h.
+GTEST_DECLARE_bool_(death_test_use_fork);
+
+namespace internal {
+
+// The value of GetTestTypeId() as seen from within the Google Test
+// library.  This is solely for testing GetTestTypeId().
+GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest;
+
+// Names of the flags (needed for parsing Google Test flags).
+const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests";
+const char kBreakOnFailureFlag[] = "break_on_failure";
+const char kCatchExceptionsFlag[] = "catch_exceptions";
+const char kColorFlag[] = "color";
+const char kFilterFlag[] = "filter";
+const char kListTestsFlag[] = "list_tests";
+const char kOutputFlag[] = "output";
+const char kPrintTimeFlag[] = "print_time";
+const char kRandomSeedFlag[] = "random_seed";
+const char kRepeatFlag[] = "repeat";
+const char kShuffleFlag[] = "shuffle";
+const char kStackTraceDepthFlag[] = "stack_trace_depth";
+const char kThrowOnFailureFlag[] = "throw_on_failure";
+
+// A valid random seed must be in [1, kMaxRandomSeed].
+const int kMaxRandomSeed = 99999;
+
+// g_help_flag is true iff the --help flag or an equivalent form is
+// specified on the command line.
+GTEST_API_ extern bool g_help_flag;
+
+// Returns the current time in milliseconds.
+GTEST_API_ TimeInMillis GetTimeInMillis();
+
+// Returns true iff Google Test should use colors in the output.
+GTEST_API_ bool ShouldUseColor(bool stdout_is_tty);
+
+// Formats the given time in milliseconds as seconds.
+GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms);
+
+// Parses a string for an Int32 flag, in the form of "--flag=value".
+//
+// On success, stores the value of the flag in *value, and returns
+// true.  On failure, returns false without changing *value.
+GTEST_API_ bool ParseInt32Flag(
+    const char* str, const char* flag, Int32* value);
+
+// Returns a random seed in range [1, kMaxRandomSeed] based on the
+// given --gtest_random_seed flag value.
+inline int GetRandomSeedFromFlag(Int32 random_seed_flag) {
+  const unsigned int raw_seed = (random_seed_flag == 0) ?
+      static_cast<unsigned int>(GetTimeInMillis()) :
+      static_cast<unsigned int>(random_seed_flag);
+
+  // Normalizes the actual seed to range [1, kMaxRandomSeed] such that
+  // it's easy to type.
+  const int normalized_seed =
+      static_cast<int>((raw_seed - 1U) %
+                       static_cast<unsigned int>(kMaxRandomSeed)) + 1;
+  return normalized_seed;
+}
+
+// Returns the first valid random seed after 'seed'.  The behavior is
+// undefined if 'seed' is invalid.  The seed after kMaxRandomSeed is
+// considered to be 1.
+inline int GetNextRandomSeed(int seed) {
+  GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed)
+      << "Invalid random seed " << seed << " - must be in [1, "
+      << kMaxRandomSeed << "].";
+  const int next_seed = seed + 1;
+  return (next_seed > kMaxRandomSeed) ? 1 : next_seed;
+}
+
+// This class saves the values of all Google Test flags in its c'tor, and
+// restores them in its d'tor.
+class GTestFlagSaver {
+ public:
+  // The c'tor.
+  GTestFlagSaver() {
+    also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests);
+    break_on_failure_ = GTEST_FLAG(break_on_failure);
+    catch_exceptions_ = GTEST_FLAG(catch_exceptions);
+    color_ = GTEST_FLAG(color);
+    death_test_style_ = GTEST_FLAG(death_test_style);
+    death_test_use_fork_ = GTEST_FLAG(death_test_use_fork);
+    filter_ = GTEST_FLAG(filter);
+    internal_run_death_test_ = GTEST_FLAG(internal_run_death_test);
+    list_tests_ = GTEST_FLAG(list_tests);
+    output_ = GTEST_FLAG(output);
+    print_time_ = GTEST_FLAG(print_time);
+    random_seed_ = GTEST_FLAG(random_seed);
+    repeat_ = GTEST_FLAG(repeat);
+    shuffle_ = GTEST_FLAG(shuffle);
+    stack_trace_depth_ = GTEST_FLAG(stack_trace_depth);
+    throw_on_failure_ = GTEST_FLAG(throw_on_failure);
+  }
+
+  // The d'tor is not virtual.  DO NOT INHERIT FROM THIS CLASS.
+  ~GTestFlagSaver() {
+    GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_;
+    GTEST_FLAG(break_on_failure) = break_on_failure_;
+    GTEST_FLAG(catch_exceptions) = catch_exceptions_;
+    GTEST_FLAG(color) = color_;
+    GTEST_FLAG(death_test_style) = death_test_style_;
+    GTEST_FLAG(death_test_use_fork) = death_test_use_fork_;
+    GTEST_FLAG(filter) = filter_;
+    GTEST_FLAG(internal_run_death_test) = internal_run_death_test_;
+    GTEST_FLAG(list_tests) = list_tests_;
+    GTEST_FLAG(output) = output_;
+    GTEST_FLAG(print_time) = print_time_;
+    GTEST_FLAG(random_seed) = random_seed_;
+    GTEST_FLAG(repeat) = repeat_;
+    GTEST_FLAG(shuffle) = shuffle_;
+    GTEST_FLAG(stack_trace_depth) = stack_trace_depth_;
+    GTEST_FLAG(throw_on_failure) = throw_on_failure_;
+  }
+ private:
+  // Fields for saving the original values of flags.
+  bool also_run_disabled_tests_;
+  bool break_on_failure_;
+  bool catch_exceptions_;
+  String color_;
+  String death_test_style_;
+  bool death_test_use_fork_;
+  String filter_;
+  String internal_run_death_test_;
+  bool list_tests_;
+  String output_;
+  bool print_time_;
+  bool pretty_;
+  internal::Int32 random_seed_;
+  internal::Int32 repeat_;
+  bool shuffle_;
+  internal::Int32 stack_trace_depth_;
+  bool throw_on_failure_;
+} GTEST_ATTRIBUTE_UNUSED_;
+
+// Converts a Unicode code point to a narrow string in UTF-8 encoding.
+// code_point parameter is of type UInt32 because wchar_t may not be
+// wide enough to contain a code point.
+// The output buffer str must containt at least 32 characters.
+// The function returns the address of the output buffer.
+// If the code_point is not a valid Unicode code point
+// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output
+// as '(Invalid Unicode 0xXXXXXXXX)'.
+GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str);
+
+// Converts a wide string to a narrow string in UTF-8 encoding.
+// The wide string is assumed to have the following encoding:
+//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS)
+//   UTF-32 if sizeof(wchar_t) == 4 (on Linux)
+// Parameter str points to a null-terminated wide string.
+// Parameter num_chars may additionally limit the number
+// of wchar_t characters processed. -1 is used when the entire string
+// should be processed.
+// If the string contains code points that are not valid Unicode code points
+// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output
+// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding
+// and contains invalid UTF-16 surrogate pairs, values in those pairs
+// will be encoded as individual Unicode characters from Basic Normal Plane.
+GTEST_API_ String WideStringToUtf8(const wchar_t* str, int num_chars);
+
+// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file
+// if the variable is present. If a file already exists at this location, this
+// function will write over it. If the variable is present, but the file cannot
+// be created, prints an error and exits.
+void WriteToShardStatusFileIfNeeded();
+
+// Checks whether sharding is enabled by examining the relevant
+// environment variable values. If the variables are present,
+// but inconsistent (e.g., shard_index >= total_shards), prints
+// an error and exits. If in_subprocess_for_death_test, sharding is
+// disabled because it must only be applied to the original test
+// process. Otherwise, we could filter out death tests we intended to execute.
+GTEST_API_ bool ShouldShard(const char* total_shards_str,
+                            const char* shard_index_str,
+                            bool in_subprocess_for_death_test);
+
+// Parses the environment variable var as an Int32. If it is unset,
+// returns default_val. If it is not an Int32, prints an error and
+// and aborts.
+GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val);
+
+// Given the total number of shards, the shard index, and the test id,
+// returns true iff the test should be run on this shard. The test id is
+// some arbitrary but unique non-negative integer assigned to each test
+// method. Assumes that 0 <= shard_index < total_shards.
+GTEST_API_ bool ShouldRunTestOnShard(
+    int total_shards, int shard_index, int test_id);
+
+// STL container utilities.
+
+// Returns the number of elements in the given container that satisfy
+// the given predicate.
+template <class Container, typename Predicate>
+inline int CountIf(const Container& c, Predicate predicate) {
+  return static_cast<int>(std::count_if(c.begin(), c.end(), predicate));
+}
+
+// Applies a function/functor to each element in the container.
+template <class Container, typename Functor>
+void ForEach(const Container& c, Functor functor) {
+  std::for_each(c.begin(), c.end(), functor);
+}
+
+// Returns the i-th element of the vector, or default_value if i is not
+// in range [0, v.size()).
+template <typename E>
+inline E GetElementOr(const std::vector<E>& v, int i, E default_value) {
+  return (i < 0 || i >= static_cast<int>(v.size())) ? default_value : v[i];
+}
+
+// Performs an in-place shuffle of a range of the vector's elements.
+// 'begin' and 'end' are element indices as an STL-style range;
+// i.e. [begin, end) are shuffled, where 'end' == size() means to
+// shuffle to the end of the vector.
+template <typename E>
+void ShuffleRange(internal::Random* random, int begin, int end,
+                  std::vector<E>* v) {
+  const int size = static_cast<int>(v->size());
+  GTEST_CHECK_(0 <= begin && begin <= size)
+      << "Invalid shuffle range start " << begin << ": must be in range [0, "
+      << size << "].";
+  GTEST_CHECK_(begin <= end && end <= size)
+      << "Invalid shuffle range finish " << end << ": must be in range ["
+      << begin << ", " << size << "].";
+
+  // Fisher-Yates shuffle, from
+  // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
+  for (int range_width = end - begin; range_width >= 2; range_width--) {
+    const int last_in_range = begin + range_width - 1;
+    const int selected = begin + random->Generate(range_width);
+    std::swap((*v)[selected], (*v)[last_in_range]);
+  }
+}
+
+// Performs an in-place shuffle of the vector's elements.
+template <typename E>
+inline void Shuffle(internal::Random* random, std::vector<E>* v) {
+  ShuffleRange(random, 0, static_cast<int>(v->size()), v);
+}
+
+// A function for deleting an object.  Handy for being used as a
+// functor.
+template <typename T>
+static void Delete(T* x) {
+  delete x;
+}
+
+// A predicate that checks the key of a TestProperty against a known key.
+//
+// TestPropertyKeyIs is copyable.
+class TestPropertyKeyIs {
+ public:
+  // Constructor.
+  //
+  // TestPropertyKeyIs has NO default constructor.
+  explicit TestPropertyKeyIs(const char* key)
+      : key_(key) {}
+
+  // Returns true iff the test name of test property matches on key_.
+  bool operator()(const TestProperty& test_property) const {
+    return String(test_property.key()).Compare(key_) == 0;
+  }
+
+ private:
+  String key_;
+};
+
+class TestInfoImpl {
+ public:
+  TestInfoImpl(TestInfo* parent, const char* test_case_name,
+               const char* name, const char* test_case_comment,
+               const char* comment, TypeId fixture_class_id,
+               internal::TestFactoryBase* factory);
+  ~TestInfoImpl();
+
+  // Returns true if this test should run.
+  bool should_run() const { return should_run_; }
+
+  // Sets the should_run member.
+  void set_should_run(bool should) { should_run_ = should; }
+
+  // Returns true if this test is disabled. Disabled tests are not run.
+  bool is_disabled() const { return is_disabled_; }
+
+  // Sets the is_disabled member.
+  void set_is_disabled(bool is) { is_disabled_ = is; }
+
+  // Returns true if this test matches the filter specified by the user.
+  bool matches_filter() const { return matches_filter_; }
+
+  // Sets the matches_filter member.
+  void set_matches_filter(bool matches) { matches_filter_ = matches; }
+
+  // Returns the test case name.
+  const char* test_case_name() const { return test_case_name_.c_str(); }
+
+  // Returns the test name.
+  const char* name() const { return name_.c_str(); }
+
+  // Returns the test case comment.
+  const char* test_case_comment() const { return test_case_comment_.c_str(); }
+
+  // Returns the test comment.
+  const char* comment() const { return comment_.c_str(); }
+
+  // Returns the ID of the test fixture class.
+  TypeId fixture_class_id() const { return fixture_class_id_; }
+
+  // Returns the test result.
+  TestResult* result() { return &result_; }
+  const TestResult* result() const { return &result_; }
+
+  // Creates the test object, runs it, records its result, and then
+  // deletes it.
+  void Run();
+
+  // Clears the test result.
+  void ClearResult() { result_.Clear(); }
+
+  // Clears the test result in the given TestInfo object.
+  static void ClearTestResult(TestInfo * test_info) {
+    test_info->impl()->ClearResult();
+  }
+
+ private:
+  // These fields are immutable properties of the test.
+  TestInfo* const parent_;          // The owner of this object
+  const String test_case_name_;     // Test case name
+  const String name_;               // Test name
+  const String test_case_comment_;  // Test case comment
+  const String comment_;            // Test comment
+  const TypeId fixture_class_id_;   // ID of the test fixture class
+  bool should_run_;                 // True iff this test should run
+  bool is_disabled_;                // True iff this test is disabled
+  bool matches_filter_;             // True if this test matches the
+                                    // user-specified filter.
+  internal::TestFactoryBase* const factory_;  // The factory that creates
+                                              // the test object
+
+  // This field is mutable and needs to be reset before running the
+  // test for the second time.
+  TestResult result_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfoImpl);
+};
+
+// Class UnitTestOptions.
+//
+// This class contains functions for processing options the user
+// specifies when running the tests.  It has only static members.
+//
+// In most cases, the user can specify an option using either an
+// environment variable or a command line flag.  E.g. you can set the
+// test filter using either GTEST_FILTER or --gtest_filter.  If both
+// the variable and the flag are present, the latter overrides the
+// former.
+class GTEST_API_ UnitTestOptions {
+ public:
+  // Functions for processing the gtest_output flag.
+
+  // Returns the output format, or "" for normal printed output.
+  static String GetOutputFormat();
+
+  // Returns the absolute path of the requested output file, or the
+  // default (test_detail.xml in the original working directory) if
+  // none was explicitly specified.
+  static String GetAbsolutePathToOutputFile();
+
+  // Functions for processing the gtest_filter flag.
+
+  // Returns true iff the wildcard pattern matches the string.  The
+  // first ':' or '\0' character in pattern marks the end of it.
+  //
+  // This recursive algorithm isn't very efficient, but is clear and
+  // works well enough for matching test names, which are short.
+  static bool PatternMatchesString(const char *pattern, const char *str);
+
+  // Returns true iff the user-specified filter matches the test case
+  // name and the test name.
+  static bool FilterMatchesTest(const String &test_case_name,
+                                const String &test_name);
+
+#if GTEST_OS_WINDOWS
+  // Function for supporting the gtest_catch_exception flag.
+
+  // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the
+  // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise.
+  // This function is useful as an __except condition.
+  static int GTestShouldProcessSEH(DWORD exception_code);
+#endif  // GTEST_OS_WINDOWS
+
+  // Returns true if "name" matches the ':' separated list of glob-style
+  // filters in "filter".
+  static bool MatchesFilter(const String& name, const char* filter);
+};
+
+// Returns the current application's name, removing directory path if that
+// is present.  Used by UnitTestOptions::GetOutputFile.
+GTEST_API_ FilePath GetCurrentExecutableName();
+
+// The role interface for getting the OS stack trace as a string.
+class OsStackTraceGetterInterface {
+ public:
+  OsStackTraceGetterInterface() {}
+  virtual ~OsStackTraceGetterInterface() {}
+
+  // Returns the current OS stack trace as a String.  Parameters:
+  //
+  //   max_depth  - the maximum number of stack frames to be included
+  //                in the trace.
+  //   skip_count - the number of top frames to be skipped; doesn't count
+  //                against max_depth.
+  virtual String CurrentStackTrace(int max_depth, int skip_count) = 0;
+
+  // UponLeavingGTest() should be called immediately before Google Test calls
+  // user code. It saves some information about the current stack that
+  // CurrentStackTrace() will use to find and hide Google Test stack frames.
+  virtual void UponLeavingGTest() = 0;
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface);
+};
+
+// A working implementation of the OsStackTraceGetterInterface interface.
+class OsStackTraceGetter : public OsStackTraceGetterInterface {
+ public:
+  OsStackTraceGetter() : caller_frame_(NULL) {}
+  virtual String CurrentStackTrace(int max_depth, int skip_count);
+  virtual void UponLeavingGTest();
+
+  // This string is inserted in place of stack frames that are part of
+  // Google Test's implementation.
+  static const char* const kElidedFramesMarker;
+
+ private:
+  Mutex mutex_;  // protects all internal state
+
+  // We save the stack frame below the frame that calls user code.
+  // We do this because the address of the frame immediately below
+  // the user code changes between the call to UponLeavingGTest()
+  // and any calls to CurrentStackTrace() from within the user code.
+  void* caller_frame_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter);
+};
+
+// Information about a Google Test trace point.
+struct TraceInfo {
+  const char* file;
+  int line;
+  String message;
+};
+
+// This is the default global test part result reporter used in UnitTestImpl.
+// This class should only be used by UnitTestImpl.
+class DefaultGlobalTestPartResultReporter
+  : public TestPartResultReporterInterface {
+ public:
+  explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test);
+  // Implements the TestPartResultReporterInterface. Reports the test part
+  // result in the current test.
+  virtual void ReportTestPartResult(const TestPartResult& result);
+
+ private:
+  UnitTestImpl* const unit_test_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter);
+};
+
+// This is the default per thread test part result reporter used in
+// UnitTestImpl. This class should only be used by UnitTestImpl.
+class DefaultPerThreadTestPartResultReporter
+    : public TestPartResultReporterInterface {
+ public:
+  explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test);
+  // Implements the TestPartResultReporterInterface. The implementation just
+  // delegates to the current global test part result reporter of *unit_test_.
+  virtual void ReportTestPartResult(const TestPartResult& result);
+
+ private:
+  UnitTestImpl* const unit_test_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter);
+};
+
+// The private implementation of the UnitTest class.  We don't protect
+// the methods under a mutex, as this class is not accessible by a
+// user and the UnitTest class that delegates work to this class does
+// proper locking.
+class GTEST_API_ UnitTestImpl {
+ public:
+  explicit UnitTestImpl(UnitTest* parent);
+  virtual ~UnitTestImpl();
+
+  // There are two different ways to register your own TestPartResultReporter.
+  // You can register your own repoter to listen either only for test results
+  // from the current thread or for results from all threads.
+  // By default, each per-thread test result repoter just passes a new
+  // TestPartResult to the global test result reporter, which registers the
+  // test part result for the currently running test.
+
+  // Returns the global test part result reporter.
+  TestPartResultReporterInterface* GetGlobalTestPartResultReporter();
+
+  // Sets the global test part result reporter.
+  void SetGlobalTestPartResultReporter(
+      TestPartResultReporterInterface* reporter);
+
+  // Returns the test part result reporter for the current thread.
+  TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread();
+
+  // Sets the test part result reporter for the current thread.
+  void SetTestPartResultReporterForCurrentThread(
+      TestPartResultReporterInterface* reporter);
+
+  // Gets the number of successful test cases.
+  int successful_test_case_count() const;
+
+  // Gets the number of failed test cases.
+  int failed_test_case_count() const;
+
+  // Gets the number of all test cases.
+  int total_test_case_count() const;
+
+  // Gets the number of all test cases that contain at least one test
+  // that should run.
+  int test_case_to_run_count() const;
+
+  // Gets the number of successful tests.
+  int successful_test_count() const;
+
+  // Gets the number of failed tests.
+  int failed_test_count() const;
+
+  // Gets the number of disabled tests.
+  int disabled_test_count() const;
+
+  // Gets the number of all tests.
+  int total_test_count() const;
+
+  // Gets the number of tests that should run.
+  int test_to_run_count() const;
+
+  // Gets the elapsed time, in milliseconds.
+  TimeInMillis elapsed_time() const { return elapsed_time_; }
+
+  // Returns true iff the unit test passed (i.e. all test cases passed).
+  bool Passed() const { return !Failed(); }
+
+  // Returns true iff the unit test failed (i.e. some test case failed
+  // or something outside of all tests failed).
+  bool Failed() const {
+    return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed();
+  }
+
+  // Gets the i-th test case among all the test cases. i can range from 0 to
+  // total_test_case_count() - 1. If i is not in that range, returns NULL.
+  const TestCase* GetTestCase(int i) const {
+    const int index = GetElementOr(test_case_indices_, i, -1);
+    return index < 0 ? NULL : test_cases_[i];
+  }
+
+  // Gets the i-th test case among all the test cases. i can range from 0 to
+  // total_test_case_count() - 1. If i is not in that range, returns NULL.
+  TestCase* GetMutableTestCase(int i) {
+    const int index = GetElementOr(test_case_indices_, i, -1);
+    return index < 0 ? NULL : test_cases_[index];
+  }
+
+  // Provides access to the event listener list.
+  TestEventListeners* listeners() { return &listeners_; }
+
+  // Returns the TestResult for the test that's currently running, or
+  // the TestResult for the ad hoc test if no test is running.
+  TestResult* current_test_result();
+
+  // Returns the TestResult for the ad hoc test.
+  const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; }
+
+  // Sets the OS stack trace getter.
+  //
+  // Does nothing if the input and the current OS stack trace getter
+  // are the same; otherwise, deletes the old getter and makes the
+  // input the current getter.
+  void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter);
+
+  // Returns the current OS stack trace getter if it is not NULL;
+  // otherwise, creates an OsStackTraceGetter, makes it the current
+  // getter, and returns it.
+  OsStackTraceGetterInterface* os_stack_trace_getter();
+
+  // Returns the current OS stack trace as a String.
+  //
+  // The maximum number of stack frames to be included is specified by
+  // the gtest_stack_trace_depth flag.  The skip_count parameter
+  // specifies the number of top frames to be skipped, which doesn't
+  // count against the number of frames to be included.
+  //
+  // For example, if Foo() calls Bar(), which in turn calls
+  // CurrentOsStackTraceExceptTop(1), Foo() will be included in the
+  // trace but Bar() and CurrentOsStackTraceExceptTop() won't.
+  String CurrentOsStackTraceExceptTop(int skip_count);
+
+  // Finds and returns a TestCase with the given name.  If one doesn't
+  // exist, creates one and returns it.
+  //
+  // Arguments:
+  //
+  //   test_case_name: name of the test case
+  //   set_up_tc:      pointer to the function that sets up the test case
+  //   tear_down_tc:   pointer to the function that tears down the test case
+  TestCase* GetTestCase(const char* test_case_name,
+                        const char* comment,
+                        Test::SetUpTestCaseFunc set_up_tc,
+                        Test::TearDownTestCaseFunc tear_down_tc);
+
+  // Adds a TestInfo to the unit test.
+  //
+  // Arguments:
+  //
+  //   set_up_tc:    pointer to the function that sets up the test case
+  //   tear_down_tc: pointer to the function that tears down the test case
+  //   test_info:    the TestInfo object
+  void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc,
+                   Test::TearDownTestCaseFunc tear_down_tc,
+                   TestInfo * test_info) {
+    // In order to support thread-safe death tests, we need to
+    // remember the original working directory when the test program
+    // was first invoked.  We cannot do this in RUN_ALL_TESTS(), as
+    // the user may have changed the current directory before calling
+    // RUN_ALL_TESTS().  Therefore we capture the current directory in
+    // AddTestInfo(), which is called to register a TEST or TEST_F
+    // before main() is reached.
+    if (original_working_dir_.IsEmpty()) {
+      original_working_dir_.Set(FilePath::GetCurrentDir());
+      GTEST_CHECK_(!original_working_dir_.IsEmpty())
+          << "Failed to get the current working directory.";
+    }
+
+    GetTestCase(test_info->test_case_name(),
+                test_info->test_case_comment(),
+                set_up_tc,
+                tear_down_tc)->AddTestInfo(test_info);
+  }
+
+#if GTEST_HAS_PARAM_TEST
+  // Returns ParameterizedTestCaseRegistry object used to keep track of
+  // value-parameterized tests and instantiate and register them.
+  internal::ParameterizedTestCaseRegistry& parameterized_test_registry() {
+    return parameterized_test_registry_;
+  }
+#endif  // GTEST_HAS_PARAM_TEST
+
+  // Sets the TestCase object for the test that's currently running.
+  void set_current_test_case(TestCase* a_current_test_case) {
+    current_test_case_ = a_current_test_case;
+  }
+
+  // Sets the TestInfo object for the test that's currently running.  If
+  // current_test_info is NULL, the assertion results will be stored in
+  // ad_hoc_test_result_.
+  void set_current_test_info(TestInfo* a_current_test_info) {
+    current_test_info_ = a_current_test_info;
+  }
+
+  // Registers all parameterized tests defined using TEST_P and
+  // INSTANTIATE_TEST_P, creating regular tests for each test/parameter
+  // combination. This method can be called more then once; it has
+  // guards protecting from registering the tests more then once.
+  // If value-parameterized tests are disabled, RegisterParameterizedTests
+  // is present but does nothing.
+  void RegisterParameterizedTests();
+
+  // Runs all tests in this UnitTest object, prints the result, and
+  // returns 0 if all tests are successful, or 1 otherwise.  If any
+  // exception is thrown during a test on Windows, this test is
+  // considered to be failed, but the rest of the tests will still be
+  // run.  (We disable exceptions on Linux and Mac OS X, so the issue
+  // doesn't apply there.)
+  int RunAllTests();
+
+  // Clears the results of all tests, including the ad hoc test.
+  void ClearResult() {
+    ForEach(test_cases_, TestCase::ClearTestCaseResult);
+    ad_hoc_test_result_.Clear();
+  }
+
+  enum ReactionToSharding {
+    HONOR_SHARDING_PROTOCOL,
+    IGNORE_SHARDING_PROTOCOL
+  };
+
+  // Matches the full name of each test against the user-specified
+  // filter to decide whether the test should run, then records the
+  // result in each TestCase and TestInfo object.
+  // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests
+  // based on sharding variables in the environment.
+  // Returns the number of tests that should run.
+  int FilterTests(ReactionToSharding shard_tests);
+
+  // Prints the names of the tests matching the user-specified filter flag.
+  void ListTestsMatchingFilter();
+
+  const TestCase* current_test_case() const { return current_test_case_; }
+  TestInfo* current_test_info() { return current_test_info_; }
+  const TestInfo* current_test_info() const { return current_test_info_; }
+
+  // Returns the vector of environments that need to be set-up/torn-down
+  // before/after the tests are run.
+  std::vector<Environment*>& environments() { return environments_; }
+
+  // Getters for the per-thread Google Test trace stack.
+  std::vector<TraceInfo>& gtest_trace_stack() {
+    return *(gtest_trace_stack_.pointer());
+  }
+  const std::vector<TraceInfo>& gtest_trace_stack() const {
+    return gtest_trace_stack_.get();
+  }
+
+#if GTEST_HAS_DEATH_TEST
+  void InitDeathTestSubprocessControlInfo() {
+    internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag());
+  }
+  // Returns a pointer to the parsed --gtest_internal_run_death_test
+  // flag, or NULL if that flag was not specified.
+  // This information is useful only in a death test child process.
+  // Must not be called before a call to InitGoogleTest.
+  const InternalRunDeathTestFlag* internal_run_death_test_flag() const {
+    return internal_run_death_test_flag_.get();
+  }
+
+  // Returns a pointer to the current death test factory.
+  internal::DeathTestFactory* death_test_factory() {
+    return death_test_factory_.get();
+  }
+
+  void SuppressTestEventsIfInSubprocess();
+
+  friend class ReplaceDeathTestFactory;
+#endif  // GTEST_HAS_DEATH_TEST
+
+  // Initializes the event listener performing XML output as specified by
+  // UnitTestOptions. Must not be called before InitGoogleTest.
+  void ConfigureXmlOutput();
+
+  // Performs initialization dependent upon flag values obtained in
+  // ParseGoogleTestFlagsOnly.  Is called from InitGoogleTest after the call to
+  // ParseGoogleTestFlagsOnly.  In case a user neglects to call InitGoogleTest
+  // this function is also called from RunAllTests.  Since this function can be
+  // called more than once, it has to be idempotent.
+  void PostFlagParsingInit();
+
+  // Gets the random seed used at the start of the current test iteration.
+  int random_seed() const { return random_seed_; }
+
+  // Gets the random number generator.
+  internal::Random* random() { return &random_; }
+
+  // Shuffles all test cases, and the tests within each test case,
+  // making sure that death tests are still run first.
+  void ShuffleTests();
+
+  // Restores the test cases and tests to their order before the first shuffle.
+  void UnshuffleTests();
+
+ private:
+  friend class ::testing::UnitTest;
+
+  // The UnitTest object that owns this implementation object.
+  UnitTest* const parent_;
+
+  // The working directory when the first TEST() or TEST_F() was
+  // executed.
+  internal::FilePath original_working_dir_;
+
+  // The default test part result reporters.
+  DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_;
+  DefaultPerThreadTestPartResultReporter
+      default_per_thread_test_part_result_reporter_;
+
+  // Points to (but doesn't own) the global test part result reporter.
+  TestPartResultReporterInterface* global_test_part_result_repoter_;
+
+  // Protects read and write access to global_test_part_result_reporter_.
+  internal::Mutex global_test_part_result_reporter_mutex_;
+
+  // Points to (but doesn't own) the per-thread test part result reporter.
+  internal::ThreadLocal<TestPartResultReporterInterface*>
+      per_thread_test_part_result_reporter_;
+
+  // The vector of environments that need to be set-up/torn-down
+  // before/after the tests are run.
+  std::vector<Environment*> environments_;
+
+  // The vector of TestCases in their original order.  It owns the
+  // elements in the vector.
+  std::vector<TestCase*> test_cases_;
+
+  // Provides a level of indirection for the test case list to allow
+  // easy shuffling and restoring the test case order.  The i-th
+  // element of this vector is the index of the i-th test case in the
+  // shuffled order.
+  std::vector<int> test_case_indices_;
+
+#if GTEST_HAS_PARAM_TEST
+  // ParameterizedTestRegistry object used to register value-parameterized
+  // tests.
+  internal::ParameterizedTestCaseRegistry parameterized_test_registry_;
+
+  // Indicates whether RegisterParameterizedTests() has been called already.
+  bool parameterized_tests_registered_;
+#endif  // GTEST_HAS_PARAM_TEST
+
+  // Index of the last death test case registered.  Initially -1.
+  int last_death_test_case_;
+
+  // This points to the TestCase for the currently running test.  It
+  // changes as Google Test goes through one test case after another.
+  // When no test is running, this is set to NULL and Google Test
+  // stores assertion results in ad_hoc_test_result_.  Initially NULL.
+  TestCase* current_test_case_;
+
+  // This points to the TestInfo for the currently running test.  It
+  // changes as Google Test goes through one test after another.  When
+  // no test is running, this is set to NULL and Google Test stores
+  // assertion results in ad_hoc_test_result_.  Initially NULL.
+  TestInfo* current_test_info_;
+
+  // Normally, a user only writes assertions inside a TEST or TEST_F,
+  // or inside a function called by a TEST or TEST_F.  Since Google
+  // Test keeps track of which test is current running, it can
+  // associate such an assertion with the test it belongs to.
+  //
+  // If an assertion is encountered when no TEST or TEST_F is running,
+  // Google Test attributes the assertion result to an imaginary "ad hoc"
+  // test, and records the result in ad_hoc_test_result_.
+  TestResult ad_hoc_test_result_;
+
+  // The list of event listeners that can be used to track events inside
+  // Google Test.
+  TestEventListeners listeners_;
+
+  // The OS stack trace getter.  Will be deleted when the UnitTest
+  // object is destructed.  By default, an OsStackTraceGetter is used,
+  // but the user can set this field to use a custom getter if that is
+  // desired.
+  OsStackTraceGetterInterface* os_stack_trace_getter_;
+
+  // True iff PostFlagParsingInit() has been called.
+  bool post_flag_parse_init_performed_;
+
+  // The random number seed used at the beginning of the test run.
+  int random_seed_;
+
+  // Our random number generator.
+  internal::Random random_;
+
+  // How long the test took to run, in milliseconds.
+  TimeInMillis elapsed_time_;
+
+#if GTEST_HAS_DEATH_TEST
+  // The decomposed components of the gtest_internal_run_death_test flag,
+  // parsed when RUN_ALL_TESTS is called.
+  internal::scoped_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_;
+  internal::scoped_ptr<internal::DeathTestFactory> death_test_factory_;
+#endif  // GTEST_HAS_DEATH_TEST
+
+  // A per-thread stack of traces created by the SCOPED_TRACE() macro.
+  internal::ThreadLocal<std::vector<TraceInfo> > gtest_trace_stack_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl);
+};  // class UnitTestImpl
+
+// Convenience function for accessing the global UnitTest
+// implementation object.
+inline UnitTestImpl* GetUnitTestImpl() {
+  return UnitTest::GetInstance()->impl();
+}
+
+// Internal helper functions for implementing the simple regular
+// expression matcher.
+GTEST_API_ bool IsInSet(char ch, const char* str);
+GTEST_API_ bool IsDigit(char ch);
+GTEST_API_ bool IsPunct(char ch);
+GTEST_API_ bool IsRepeat(char ch);
+GTEST_API_ bool IsWhiteSpace(char ch);
+GTEST_API_ bool IsWordChar(char ch);
+GTEST_API_ bool IsValidEscape(char ch);
+GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch);
+GTEST_API_ bool ValidateRegex(const char* regex);
+GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str);
+GTEST_API_ bool MatchRepetitionAndRegexAtHead(
+    bool escaped, char ch, char repeat, const char* regex, const char* str);
+GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str);
+
+// Parses the command line for Google Test flags, without initializing
+// other parts of Google Test.
+GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv);
+GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv);
+
+#if GTEST_HAS_DEATH_TEST
+
+// Returns the message describing the last system error, regardless of the
+// platform.
+String GetLastErrnoDescription();
+
+#if GTEST_OS_WINDOWS
+// Provides leak-safe Windows kernel handle ownership.
+class AutoHandle {
+ public:
+  AutoHandle() : handle_(INVALID_HANDLE_VALUE) {}
+  explicit AutoHandle(HANDLE handle) : handle_(handle) {}
+
+  ~AutoHandle() { Reset(); }
+
+  HANDLE Get() const { return handle_; }
+  void Reset() { Reset(INVALID_HANDLE_VALUE); }
+  void Reset(HANDLE handle) {
+    if (handle != handle_) {
+      if (handle_ != INVALID_HANDLE_VALUE)
+        ::CloseHandle(handle_);
+      handle_ = handle;
+    }
+  }
+
+ private:
+  HANDLE handle_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle);
+};
+#endif  // GTEST_OS_WINDOWS
+
+// Attempts to parse a string into a positive integer pointed to by the
+// number parameter.  Returns true if that is possible.
+// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use
+// it here.
+template <typename Integer>
+bool ParseNaturalNumber(const ::std::string& str, Integer* number) {
+  // Fail fast if the given string does not begin with a digit;
+  // this bypasses strtoXXX's "optional leading whitespace and plus
+  // or minus sign" semantics, which are undesirable here.
+  if (str.empty() || !isdigit(str[0])) {
+    return false;
+  }
+  errno = 0;
+
+  char* end;
+  // BiggestConvertible is the largest integer type that system-provided
+  // string-to-number conversion routines can return.
+#if GTEST_OS_WINDOWS && !defined(__GNUC__)
+  // MSVC and C++ Builder define __int64 instead of the standard long long.
+  typedef unsigned __int64 BiggestConvertible;
+  const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10);
+#else
+  typedef unsigned long long BiggestConvertible;  // NOLINT
+  const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10);
+#endif  // GTEST_OS_WINDOWS && !defined(__GNUC__)
+  const bool parse_success = *end == '\0' && errno == 0;
+
+  // TODO(vladl@google.com): Convert this to compile time assertion when it is
+  // available.
+  GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed));
+
+  const Integer result = static_cast<Integer>(parsed);
+  if (parse_success && static_cast<BiggestConvertible>(result) == parsed) {
+    *number = result;
+    return true;
+  }
+  return false;
+}
+#endif  // GTEST_HAS_DEATH_TEST
+
+// TestResult contains some private methods that should be hidden from
+// Google Test user but are required for testing. This class allow our tests
+// to access them.
+//
+// This class is supplied only for the purpose of testing Google Test's own
+// constructs. Do not use it in user tests, either directly or indirectly.
+class TestResultAccessor {
+ public:
+  static void RecordProperty(TestResult* test_result,
+                             const TestProperty& property) {
+    test_result->RecordProperty(property);
+  }
+
+  static void ClearTestPartResults(TestResult* test_result) {
+    test_result->ClearTestPartResults();
+  }
+
+  static const std::vector<testing::TestPartResult>& test_part_results(
+      const TestResult& test_result) {
+    return test_result.test_part_results();
+  }
+};
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_SRC_GTEST_INTERNAL_INL_H_
diff --git a/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-internal.h b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-internal.h
new file mode 100644
index 0000000..0b90132
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-internal.h
@@ -0,0 +1,943 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file declares functions and macros used internally by
+// Google Test.  They are subject to change without notice.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
+
+#include <gtest/internal/gtest-port.h>
+
+#if GTEST_OS_LINUX
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#endif  // GTEST_OS_LINUX
+
+#include <ctype.h>
+#include <string.h>
+#include <iomanip>
+#include <limits>
+#include <set>
+
+#include <gtest/internal/gtest-string.h>
+#include <gtest/internal/gtest-filepath.h>
+#include <gtest/internal/gtest-type-util.h>
+
+#include "llvm/Support/raw_os_ostream.h"
+
+// Due to C++ preprocessor weirdness, we need double indirection to
+// concatenate two tokens when one of them is __LINE__.  Writing
+//
+//   foo ## __LINE__
+//
+// will result in the token foo__LINE__, instead of foo followed by
+// the current line number.  For more details, see
+// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6
+#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)
+#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar
+
+// Google Test defines the testing::Message class to allow construction of
+// test messages via the << operator.  The idea is that anything
+// streamable to std::ostream can be streamed to a testing::Message.
+// This allows a user to use his own types in Google Test assertions by
+// overloading the << operator.
+//
+// util/gtl/stl_logging-inl.h overloads << for STL containers.  These
+// overloads cannot be defined in the std namespace, as that will be
+// undefined behavior.  Therefore, they are defined in the global
+// namespace instead.
+//
+// C++'s symbol lookup rule (i.e. Koenig lookup) says that these
+// overloads are visible in either the std namespace or the global
+// namespace, but not other namespaces, including the testing
+// namespace which Google Test's Message class is in.
+//
+// To allow STL containers (and other types that has a << operator
+// defined in the global namespace) to be used in Google Test assertions,
+// testing::Message must access the custom << operator from the global
+// namespace.  Hence this helper function.
+//
+// Note: Jeffrey Yasskin suggested an alternative fix by "using
+// ::operator<<;" in the definition of Message's operator<<.  That fix
+// doesn't require a helper function, but unfortunately doesn't
+// compile with MSVC.
+
+// LLVM INTERNAL CHANGE: To allow operator<< to work with both
+// std::ostreams and LLVM's raw_ostreams, we define a special
+// std::ostream with an implicit conversion to raw_ostream& and stream
+// to that.  This causes the compiler to prefer std::ostream overloads
+// but still find raw_ostream& overloads.
+namespace llvm {
+class convertible_fwd_ostream : public std::ostream {
+  std::ostream& os_;
+  raw_os_ostream ros_;
+
+public:
+  convertible_fwd_ostream(std::ostream& os)
+    : std::ostream(os.rdbuf()), os_(os), ros_(*this) {}
+  operator raw_ostream&() { return ros_; }
+};
+}
+template <typename T>
+inline void GTestStreamToHelper(std::ostream* os, const T& val) {
+  llvm::convertible_fwd_ostream cos(*os);
+  cos << val;
+}
+
+namespace testing {
+
+// Forward declaration of classes.
+
+class AssertionResult;                 // Result of an assertion.
+class Message;                         // Represents a failure message.
+class Test;                            // Represents a test.
+class TestInfo;                        // Information about a test.
+class TestPartResult;                  // Result of a test part.
+class UnitTest;                        // A collection of test cases.
+
+namespace internal {
+
+struct TraceInfo;                      // Information about a trace point.
+class ScopedTrace;                     // Implements scoped trace.
+class TestInfoImpl;                    // Opaque implementation of TestInfo
+class UnitTestImpl;                    // Opaque implementation of UnitTest
+
+// How many times InitGoogleTest() has been called.
+extern int g_init_gtest_count;
+
+// The text used in failure messages to indicate the start of the
+// stack trace.
+GTEST_API_ extern const char kStackTraceMarker[];
+
+// A secret type that Google Test users don't know about.  It has no
+// definition on purpose.  Therefore it's impossible to create a
+// Secret object, which is what we want.
+class Secret;
+
+// Two overloaded helpers for checking at compile time whether an
+// expression is a null pointer literal (i.e. NULL or any 0-valued
+// compile-time integral constant).  Their return values have
+// different sizes, so we can use sizeof() to test which version is
+// picked by the compiler.  These helpers have no implementations, as
+// we only need their signatures.
+//
+// Given IsNullLiteralHelper(x), the compiler will pick the first
+// version if x can be implicitly converted to Secret*, and pick the
+// second version otherwise.  Since Secret is a secret and incomplete
+// type, the only expression a user can write that has type Secret* is
+// a null pointer literal.  Therefore, we know that x is a null
+// pointer literal if and only if the first version is picked by the
+// compiler.
+char IsNullLiteralHelper(Secret* p);
+char (&IsNullLiteralHelper(...))[2];  // NOLINT
+
+// A compile-time bool constant that is true if and only if x is a
+// null pointer literal (i.e. NULL or any 0-valued compile-time
+// integral constant).
+#ifdef GTEST_ELLIPSIS_NEEDS_POD_
+// We lose support for NULL detection where the compiler doesn't like
+// passing non-POD classes through ellipsis (...).
+#define GTEST_IS_NULL_LITERAL_(x) false
+#else
+#define GTEST_IS_NULL_LITERAL_(x) \
+    (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1)
+#endif  // GTEST_ELLIPSIS_NEEDS_POD_
+
+// Appends the user-supplied message to the Google-Test-generated message.
+GTEST_API_ String AppendUserMessage(const String& gtest_msg,
+                                    const Message& user_msg);
+
+// A helper class for creating scoped traces in user programs.
+class GTEST_API_ ScopedTrace {
+ public:
+  // The c'tor pushes the given source file location and message onto
+  // a trace stack maintained by Google Test.
+  ScopedTrace(const char* file, int line, const Message& message);
+
+  // The d'tor pops the info pushed by the c'tor.
+  //
+  // Note that the d'tor is not virtual in order to be efficient.
+  // Don't inherit from ScopedTrace!
+  ~ScopedTrace();
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace);
+} GTEST_ATTRIBUTE_UNUSED_;  // A ScopedTrace object does its job in its
+                            // c'tor and d'tor.  Therefore it doesn't
+                            // need to be used otherwise.
+
+// Converts a streamable value to a String.  A NULL pointer is
+// converted to "(null)".  When the input value is a ::string,
+// ::std::string, ::wstring, or ::std::wstring object, each NUL
+// character in it is replaced with "\\0".
+// Declared here but defined in gtest.h, so that it has access
+// to the definition of the Message class, required by the ARM
+// compiler.
+template <typename T>
+String StreamableToString(const T& streamable);
+
+// Formats a value to be used in a failure message.
+
+#ifdef GTEST_NEEDS_IS_POINTER_
+
+// These are needed as the Nokia Symbian and IBM XL C/C++ compilers
+// cannot decide between const T& and const T* in a function template.
+// These compilers _can_ decide between class template specializations
+// for T and T*, so a tr1::type_traits-like is_pointer works, and we
+// can overload on that.
+
+// This overload makes sure that all pointers (including
+// those to char or wchar_t) are printed as raw pointers.
+template <typename T>
+inline String FormatValueForFailureMessage(internal::true_type /*dummy*/,
+                                           T* pointer) {
+  return StreamableToString(static_cast<const void*>(pointer));
+}
+
+template <typename T>
+inline String FormatValueForFailureMessage(internal::false_type /*dummy*/,
+                                           const T& value) {
+  return StreamableToString(value);
+}
+
+template <typename T>
+inline String FormatForFailureMessage(const T& value) {
+  return FormatValueForFailureMessage(
+      typename internal::is_pointer<T>::type(), value);
+}
+
+#else
+
+// These are needed as the above solution using is_pointer has the
+// limitation that T cannot be a type without external linkage, when
+// compiled using MSVC.
+
+template <typename T>
+inline String FormatForFailureMessage(const T& value) {
+  return StreamableToString(value);
+}
+
+// This overload makes sure that all pointers (including
+// those to char or wchar_t) are printed as raw pointers.
+template <typename T>
+inline String FormatForFailureMessage(T* pointer) {
+  return StreamableToString(static_cast<const void*>(pointer));
+}
+
+#endif  // GTEST_NEEDS_IS_POINTER_
+
+// These overloaded versions handle narrow and wide characters.
+GTEST_API_ String FormatForFailureMessage(char ch);
+GTEST_API_ String FormatForFailureMessage(wchar_t wchar);
+
+// When this operand is a const char* or char*, and the other operand
+// is a ::std::string or ::string, we print this operand as a C string
+// rather than a pointer.  We do the same for wide strings.
+
+// This internal macro is used to avoid duplicated code.
+#define GTEST_FORMAT_IMPL_(operand2_type, operand1_printer)\
+inline String FormatForComparisonFailureMessage(\
+    operand2_type::value_type* str, const operand2_type& /*operand2*/) {\
+  return operand1_printer(str);\
+}\
+inline String FormatForComparisonFailureMessage(\
+    const operand2_type::value_type* str, const operand2_type& /*operand2*/) {\
+  return operand1_printer(str);\
+}
+
+GTEST_FORMAT_IMPL_(::std::string, String::ShowCStringQuoted)
+#if GTEST_HAS_STD_WSTRING
+GTEST_FORMAT_IMPL_(::std::wstring, String::ShowWideCStringQuoted)
+#endif  // GTEST_HAS_STD_WSTRING
+
+#if GTEST_HAS_GLOBAL_STRING
+GTEST_FORMAT_IMPL_(::string, String::ShowCStringQuoted)
+#endif  // GTEST_HAS_GLOBAL_STRING
+#if GTEST_HAS_GLOBAL_WSTRING
+GTEST_FORMAT_IMPL_(::wstring, String::ShowWideCStringQuoted)
+#endif  // GTEST_HAS_GLOBAL_WSTRING
+
+#undef GTEST_FORMAT_IMPL_
+
+// Constructs and returns the message for an equality assertion
+// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.
+//
+// The first four parameters are the expressions used in the assertion
+// and their values, as strings.  For example, for ASSERT_EQ(foo, bar)
+// where foo is 5 and bar is 6, we have:
+//
+//   expected_expression: "foo"
+//   actual_expression:   "bar"
+//   expected_value:      "5"
+//   actual_value:        "6"
+//
+// The ignoring_case parameter is true iff the assertion is a
+// *_STRCASEEQ*.  When it's true, the string " (ignoring case)" will
+// be inserted into the message.
+GTEST_API_ AssertionResult EqFailure(const char* expected_expression,
+                                     const char* actual_expression,
+                                     const String& expected_value,
+                                     const String& actual_value,
+                                     bool ignoring_case);
+
+// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.
+GTEST_API_ String GetBoolAssertionFailureMessage(
+    const AssertionResult& assertion_result,
+    const char* expression_text,
+    const char* actual_predicate_value,
+    const char* expected_predicate_value);
+
+// This template class represents an IEEE floating-point number
+// (either single-precision or double-precision, depending on the
+// template parameters).
+//
+// The purpose of this class is to do more sophisticated number
+// comparison.  (Due to round-off error, etc, it's very unlikely that
+// two floating-points will be equal exactly.  Hence a naive
+// comparison by the == operation often doesn't work.)
+//
+// Format of IEEE floating-point:
+//
+//   The most-significant bit being the leftmost, an IEEE
+//   floating-point looks like
+//
+//     sign_bit exponent_bits fraction_bits
+//
+//   Here, sign_bit is a single bit that designates the sign of the
+//   number.
+//
+//   For float, there are 8 exponent bits and 23 fraction bits.
+//
+//   For double, there are 11 exponent bits and 52 fraction bits.
+//
+//   More details can be found at
+//   http://en.wikipedia.org/wiki/IEEE_floating-point_standard.
+//
+// Template parameter:
+//
+//   RawType: the raw floating-point type (either float or double)
+template <typename RawType>
+class FloatingPoint {
+ public:
+  // Defines the unsigned integer type that has the same size as the
+  // floating point number.
+  typedef typename TypeWithSize<sizeof(RawType)>::UInt Bits;
+
+  // Constants.
+
+  // # of bits in a number.
+  static const size_t kBitCount = 8*sizeof(RawType);
+
+  // # of fraction bits in a number.
+  static const size_t kFractionBitCount =
+    std::numeric_limits<RawType>::digits - 1;
+
+  // # of exponent bits in a number.
+  static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount;
+
+  // The mask for the sign bit.
+  static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1);
+
+  // The mask for the fraction bits.
+  static const Bits kFractionBitMask =
+    ~static_cast<Bits>(0) >> (kExponentBitCount + 1);
+
+  // The mask for the exponent bits.
+  static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask);
+
+  // How many ULP's (Units in the Last Place) we want to tolerate when
+  // comparing two numbers.  The larger the value, the more error we
+  // allow.  A 0 value means that two numbers must be exactly the same
+  // to be considered equal.
+  //
+  // The maximum error of a single floating-point operation is 0.5
+  // units in the last place.  On Intel CPU's, all floating-point
+  // calculations are done with 80-bit precision, while double has 64
+  // bits.  Therefore, 4 should be enough for ordinary use.
+  //
+  // See the following article for more details on ULP:
+  // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm.
+  static const size_t kMaxUlps = 4;
+
+  // Constructs a FloatingPoint from a raw floating-point number.
+  //
+  // On an Intel CPU, passing a non-normalized NAN (Not a Number)
+  // around may change its bits, although the new value is guaranteed
+  // to be also a NAN.  Therefore, don't expect this constructor to
+  // preserve the bits in x when x is a NAN.
+  explicit FloatingPoint(const RawType& x) { u_.value_ = x; }
+
+  // Static methods
+
+  // Reinterprets a bit pattern as a floating-point number.
+  //
+  // This function is needed to test the AlmostEquals() method.
+  static RawType ReinterpretBits(const Bits bits) {
+    FloatingPoint fp(0);
+    fp.u_.bits_ = bits;
+    return fp.u_.value_;
+  }
+
+  // Returns the floating-point number that represent positive infinity.
+  static RawType Infinity() {
+    return ReinterpretBits(kExponentBitMask);
+  }
+
+  // Non-static methods
+
+  // Returns the bits that represents this number.
+  const Bits &bits() const { return u_.bits_; }
+
+  // Returns the exponent bits of this number.
+  Bits exponent_bits() const { return kExponentBitMask & u_.bits_; }
+
+  // Returns the fraction bits of this number.
+  Bits fraction_bits() const { return kFractionBitMask & u_.bits_; }
+
+  // Returns the sign bit of this number.
+  Bits sign_bit() const { return kSignBitMask & u_.bits_; }
+
+  // Returns true iff this is NAN (not a number).
+  bool is_nan() const {
+    // It's a NAN if the exponent bits are all ones and the fraction
+    // bits are not entirely zeros.
+    return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0);
+  }
+
+  // Returns true iff this number is at most kMaxUlps ULP's away from
+  // rhs.  In particular, this function:
+  //
+  //   - returns false if either number is (or both are) NAN.
+  //   - treats really large numbers as almost equal to infinity.
+  //   - thinks +0.0 and -0.0 are 0 DLP's apart.
+  bool AlmostEquals(const FloatingPoint& rhs) const {
+    // The IEEE standard says that any comparison operation involving
+    // a NAN must return false.
+    if (is_nan() || rhs.is_nan()) return false;
+
+    return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_)
+        <= kMaxUlps;
+  }
+
+ private:
+  // The data type used to store the actual floating-point number.
+  union FloatingPointUnion {
+    RawType value_;  // The raw floating-point number.
+    Bits bits_;      // The bits that represent the number.
+  };
+
+  // Converts an integer from the sign-and-magnitude representation to
+  // the biased representation.  More precisely, let N be 2 to the
+  // power of (kBitCount - 1), an integer x is represented by the
+  // unsigned number x + N.
+  //
+  // For instance,
+  //
+  //   -N + 1 (the most negative number representable using
+  //          sign-and-magnitude) is represented by 1;
+  //   0      is represented by N; and
+  //   N - 1  (the biggest number representable using
+  //          sign-and-magnitude) is represented by 2N - 1.
+  //
+  // Read http://en.wikipedia.org/wiki/Signed_number_representations
+  // for more details on signed number representations.
+  static Bits SignAndMagnitudeToBiased(const Bits &sam) {
+    if (kSignBitMask & sam) {
+      // sam represents a negative number.
+      return ~sam + 1;
+    } else {
+      // sam represents a positive number.
+      return kSignBitMask | sam;
+    }
+  }
+
+  // Given two numbers in the sign-and-magnitude representation,
+  // returns the distance between them as an unsigned number.
+  static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1,
+                                                     const Bits &sam2) {
+    const Bits biased1 = SignAndMagnitudeToBiased(sam1);
+    const Bits biased2 = SignAndMagnitudeToBiased(sam2);
+    return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
+  }
+
+  FloatingPointUnion u_;
+};
+
+// Typedefs the instances of the FloatingPoint template class that we
+// care to use.
+typedef FloatingPoint<float> Float;
+typedef FloatingPoint<double> Double;
+
+// In order to catch the mistake of putting tests that use different
+// test fixture classes in the same test case, we need to assign
+// unique IDs to fixture classes and compare them.  The TypeId type is
+// used to hold such IDs.  The user should treat TypeId as an opaque
+// type: the only operation allowed on TypeId values is to compare
+// them for equality using the == operator.
+typedef const void* TypeId;
+
+template <typename T>
+class TypeIdHelper {
+ public:
+  // dummy_ must not have a const type.  Otherwise an overly eager
+  // compiler (e.g. MSVC 7.1 & 8.0) may try to merge
+  // TypeIdHelper<T>::dummy_ for different Ts as an "optimization".
+  static bool dummy_;
+};
+
+template <typename T>
+bool TypeIdHelper<T>::dummy_ = false;
+
+// GetTypeId<T>() returns the ID of type T.  Different values will be
+// returned for different types.  Calling the function twice with the
+// same type argument is guaranteed to return the same ID.
+template <typename T>
+TypeId GetTypeId() {
+  // The compiler is required to allocate a different
+  // TypeIdHelper<T>::dummy_ variable for each T used to instantiate
+  // the template.  Therefore, the address of dummy_ is guaranteed to
+  // be unique.
+  return &(TypeIdHelper<T>::dummy_);
+}
+
+// Returns the type ID of ::testing::Test.  Always call this instead
+// of GetTypeId< ::testing::Test>() to get the type ID of
+// ::testing::Test, as the latter may give the wrong result due to a
+// suspected linker bug when compiling Google Test as a Mac OS X
+// framework.
+GTEST_API_ TypeId GetTestTypeId();
+
+// Defines the abstract factory interface that creates instances
+// of a Test object.
+class TestFactoryBase {
+ public:
+  virtual ~TestFactoryBase() {}
+
+  // Creates a test instance to run. The instance is both created and destroyed
+  // within TestInfoImpl::Run()
+  virtual Test* CreateTest() = 0;
+
+ protected:
+  TestFactoryBase() {}
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase);
+};
+
+// This class provides implementation of TeastFactoryBase interface.
+// It is used in TEST and TEST_F macros.
+template <class TestClass>
+class TestFactoryImpl : public TestFactoryBase {
+ public:
+  virtual Test* CreateTest() { return new TestClass; }
+};
+
+#if GTEST_OS_WINDOWS
+
+// Predicate-formatters for implementing the HRESULT checking macros
+// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}
+// We pass a long instead of HRESULT to avoid causing an
+// include dependency for the HRESULT type.
+GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr,
+                                            long hr);  // NOLINT
+GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr,
+                                            long hr);  // NOLINT
+
+#endif  // GTEST_OS_WINDOWS
+
+// Formats a source file path and a line number as they would appear
+// in a compiler error message.
+inline String FormatFileLocation(const char* file, int line) {
+  const char* const file_name = file == NULL ? "unknown file" : file;
+  if (line < 0) {
+    return String::Format("%s:", file_name);
+  }
+#ifdef _MSC_VER
+  return String::Format("%s(%d):", file_name, line);
+#else
+  return String::Format("%s:%d:", file_name, line);
+#endif  // _MSC_VER
+}
+
+// Types of SetUpTestCase() and TearDownTestCase() functions.
+typedef void (*SetUpTestCaseFunc)();
+typedef void (*TearDownTestCaseFunc)();
+
+// Creates a new TestInfo object and registers it with Google Test;
+// returns the created object.
+//
+// Arguments:
+//
+//   test_case_name:   name of the test case
+//   name:             name of the test
+//   test_case_comment: a comment on the test case that will be included in
+//                      the test output
+//   comment:          a comment on the test that will be included in the
+//                     test output
+//   fixture_class_id: ID of the test fixture class
+//   set_up_tc:        pointer to the function that sets up the test case
+//   tear_down_tc:     pointer to the function that tears down the test case
+//   factory:          pointer to the factory that creates a test object.
+//                     The newly created TestInfo instance will assume
+//                     ownership of the factory object.
+GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
+    const char* test_case_name, const char* name,
+    const char* test_case_comment, const char* comment,
+    TypeId fixture_class_id,
+    SetUpTestCaseFunc set_up_tc,
+    TearDownTestCaseFunc tear_down_tc,
+    TestFactoryBase* factory);
+
+// If *pstr starts with the given prefix, modifies *pstr to be right
+// past the prefix and returns true; otherwise leaves *pstr unchanged
+// and returns false.  None of pstr, *pstr, and prefix can be NULL.
+bool SkipPrefix(const char* prefix, const char** pstr);
+
+#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+// State of the definition of a type-parameterized test case.
+class GTEST_API_ TypedTestCasePState {
+ public:
+  TypedTestCasePState() : registered_(false) {}
+
+  // Adds the given test name to defined_test_names_ and return true
+  // if the test case hasn't been registered; otherwise aborts the
+  // program.
+  bool AddTestName(const char* file, int line, const char* case_name,
+                   const char* test_name) {
+    if (registered_) {
+      fprintf(stderr, "%s Test %s must be defined before "
+              "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n",
+              FormatFileLocation(file, line).c_str(), test_name, case_name);
+      fflush(stderr);
+      posix::Abort();
+    }
+    defined_test_names_.insert(test_name);
+    return true;
+  }
+
+  // Verifies that registered_tests match the test names in
+  // defined_test_names_; returns registered_tests if successful, or
+  // aborts the program otherwise.
+  const char* VerifyRegisteredTestNames(
+      const char* file, int line, const char* registered_tests);
+
+ private:
+  bool registered_;
+  ::std::set<const char*> defined_test_names_;
+};
+
+// Skips to the first non-space char after the first comma in 'str';
+// returns NULL if no comma is found in 'str'.
+inline const char* SkipComma(const char* str) {
+  const char* comma = strchr(str, ',');
+  if (comma == NULL) {
+    return NULL;
+  }
+  while (isspace(*(++comma))) {}
+  return comma;
+}
+
+// Returns the prefix of 'str' before the first comma in it; returns
+// the entire string if it contains no comma.
+inline String GetPrefixUntilComma(const char* str) {
+  const char* comma = strchr(str, ',');
+  return comma == NULL ? String(str) : String(str, comma - str);
+}
+
+// TypeParameterizedTest<Fixture, TestSel, Types>::Register()
+// registers a list of type-parameterized tests with Google Test.  The
+// return value is insignificant - we just need to return something
+// such that we can call this function in a namespace scope.
+//
+// Implementation note: The GTEST_TEMPLATE_ macro declares a template
+// template parameter.  It's defined in gtest-type-util.h.
+template <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types>
+class TypeParameterizedTest {
+ public:
+  // 'index' is the index of the test in the type list 'Types'
+  // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase,
+  // Types).  Valid values for 'index' are [0, N - 1] where N is the
+  // length of Types.
+  static bool Register(const char* prefix, const char* case_name,
+                       const char* test_names, int index) {
+    typedef typename Types::Head Type;
+    typedef Fixture<Type> FixtureClass;
+    typedef typename GTEST_BIND_(TestSel, Type) TestClass;
+
+    // First, registers the first type-parameterized test in the type
+    // list.
+    MakeAndRegisterTestInfo(
+        String::Format("%s%s%s/%d", prefix, prefix[0] == '\0' ? "" : "/",
+                       case_name, index).c_str(),
+        GetPrefixUntilComma(test_names).c_str(),
+        String::Format("TypeParam = %s", GetTypeName<Type>().c_str()).c_str(),
+        "",
+        GetTypeId<FixtureClass>(),
+        TestClass::SetUpTestCase,
+        TestClass::TearDownTestCase,
+        new TestFactoryImpl<TestClass>);
+
+    // Next, recurses (at compile time) with the tail of the type list.
+    return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>
+        ::Register(prefix, case_name, test_names, index + 1);
+  }
+};
+
+// The base case for the compile time recursion.
+template <GTEST_TEMPLATE_ Fixture, class TestSel>
+class TypeParameterizedTest<Fixture, TestSel, Types0> {
+ public:
+  static bool Register(const char* /*prefix*/, const char* /*case_name*/,
+                       const char* /*test_names*/, int /*index*/) {
+    return true;
+  }
+};
+
+// TypeParameterizedTestCase<Fixture, Tests, Types>::Register()
+// registers *all combinations* of 'Tests' and 'Types' with Google
+// Test.  The return value is insignificant - we just need to return
+// something such that we can call this function in a namespace scope.
+template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>
+class TypeParameterizedTestCase {
+ public:
+  static bool Register(const char* prefix, const char* case_name,
+                       const char* test_names) {
+    typedef typename Tests::Head Head;
+
+    // First, register the first test in 'Test' for each type in 'Types'.
+    TypeParameterizedTest<Fixture, Head, Types>::Register(
+        prefix, case_name, test_names, 0);
+
+    // Next, recurses (at compile time) with the tail of the test list.
+    return TypeParameterizedTestCase<Fixture, typename Tests::Tail, Types>
+        ::Register(prefix, case_name, SkipComma(test_names));
+  }
+};
+
+// The base case for the compile time recursion.
+template <GTEST_TEMPLATE_ Fixture, typename Types>
+class TypeParameterizedTestCase<Fixture, Templates0, Types> {
+ public:
+  static bool Register(const char* /*prefix*/, const char* /*case_name*/,
+                       const char* /*test_names*/) {
+    return true;
+  }
+};
+
+#endif  // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+// Returns the current OS stack trace as a String.
+//
+// The maximum number of stack frames to be included is specified by
+// the gtest_stack_trace_depth flag.  The skip_count parameter
+// specifies the number of top frames to be skipped, which doesn't
+// count against the number of frames to be included.
+//
+// For example, if Foo() calls Bar(), which in turn calls
+// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
+// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
+GTEST_API_ String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test,
+                                                  int skip_count);
+
+// Helpers for suppressing warnings on unreachable code or constant
+// condition.
+
+// Always returns true.
+GTEST_API_ bool AlwaysTrue();
+
+// Always returns false.
+inline bool AlwaysFalse() { return !AlwaysTrue(); }
+
+// A simple Linear Congruential Generator for generating random
+// numbers with a uniform distribution.  Unlike rand() and srand(), it
+// doesn't use global state (and therefore can't interfere with user
+// code).  Unlike rand_r(), it's portable.  An LCG isn't very random,
+// but it's good enough for our purposes.
+class GTEST_API_ Random {
+ public:
+  static const UInt32 kMaxRange = 1u << 31;
+
+  explicit Random(UInt32 seed) : state_(seed) {}
+
+  void Reseed(UInt32 seed) { state_ = seed; }
+
+  // Generates a random number from [0, range).  Crashes if 'range' is
+  // 0 or greater than kMaxRange.
+  UInt32 Generate(UInt32 range);
+
+ private:
+  UInt32 state_;
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(Random);
+};
+
+}  // namespace internal
+}  // namespace testing
+
+#define GTEST_MESSAGE_(message, result_type) \
+  ::testing::internal::AssertHelper(result_type, __FILE__, __LINE__, message) \
+    = ::testing::Message()
+
+#define GTEST_FATAL_FAILURE_(message) \
+  return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure)
+
+#define GTEST_NONFATAL_FAILURE_(message) \
+  GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure)
+
+#define GTEST_SUCCESS_(message) \
+  GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess)
+
+// Suppresses MSVC warnings 4072 (unreachable code) for the code following
+// statement if it returns or throws (or doesn't return or throw in some
+// situations).
+#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \
+  if (::testing::internal::AlwaysTrue()) { statement; }
+
+#define GTEST_TEST_THROW_(statement, expected_exception, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (const char* gtest_msg = "") { \
+    bool gtest_caught_expected = false; \
+    try { \
+      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+    } \
+    catch (expected_exception const&) { \
+      gtest_caught_expected = true; \
+    } \
+    catch (...) { \
+      gtest_msg = "Expected: " #statement " throws an exception of type " \
+                  #expected_exception ".\n  Actual: it throws a different " \
+                  "type."; \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
+    } \
+    if (!gtest_caught_expected) { \
+      gtest_msg = "Expected: " #statement " throws an exception of type " \
+                  #expected_exception ".\n  Actual: it throws nothing."; \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
+    } \
+  } else \
+    GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \
+      fail(gtest_msg)
+
+#define GTEST_TEST_NO_THROW_(statement, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (const char* gtest_msg = "") { \
+    try { \
+      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+    } \
+    catch (...) { \
+      gtest_msg = "Expected: " #statement " doesn't throw an exception.\n" \
+                  "  Actual: it throws."; \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \
+    } \
+  } else \
+    GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \
+      fail(gtest_msg)
+
+#define GTEST_TEST_ANY_THROW_(statement, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (const char* gtest_msg = "") { \
+    bool gtest_caught_any = false; \
+    try { \
+      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+    } \
+    catch (...) { \
+      gtest_caught_any = true; \
+    } \
+    if (!gtest_caught_any) { \
+      gtest_msg = "Expected: " #statement " throws an exception.\n" \
+                  "  Actual: it doesn't."; \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \
+    } \
+  } else \
+    GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \
+      fail(gtest_msg)
+
+
+// Implements Boolean test assertions such as EXPECT_TRUE. expression can be
+// either a boolean expression or an AssertionResult. text is a textual
+// represenation of expression as it was passed into the EXPECT_TRUE.
+#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (const ::testing::AssertionResult gtest_ar_ = \
+      ::testing::AssertionResult(expression)) \
+    ; \
+  else \
+    fail(::testing::internal::GetBoolAssertionFailureMessage(\
+        gtest_ar_, text, #actual, #expected).c_str())
+
+#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (const char* gtest_msg = "") { \
+    ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \
+    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+    if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \
+      gtest_msg = "Expected: " #statement " doesn't generate new fatal " \
+                  "failures in the current thread.\n" \
+                  "  Actual: it does."; \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \
+    } \
+  } else \
+    GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \
+      fail(gtest_msg)
+
+// Expands to the name of the class that implements the given test.
+#define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
+  test_case_name##_##test_name##_Test
+
+// Helper macro for defining tests.
+#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\
+class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
+ public:\
+  GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\
+ private:\
+  virtual void TestBody();\
+  static ::testing::TestInfo* const test_info_;\
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(\
+      GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\
+};\
+\
+::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\
+  ::test_info_ =\
+    ::testing::internal::MakeAndRegisterTestInfo(\
+        #test_case_name, #test_name, "", "", \
+        (parent_id), \
+        parent_class::SetUpTestCase, \
+        parent_class::TearDownTestCase, \
+        new ::testing::internal::TestFactoryImpl<\
+            GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\
+void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
diff --git a/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-linked_ptr.h b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-linked_ptr.h
new file mode 100644
index 0000000..2404ea8
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-linked_ptr.h
@@ -0,0 +1,243 @@
+// Copyright 2003 Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Dan Egnor (egnor@google.com)
+//
+// A "smart" pointer type with reference tracking.  Every pointer to a
+// particular object is kept on a circular linked list.  When the last pointer
+// to an object is destroyed or reassigned, the object is deleted.
+//
+// Used properly, this deletes the object when the last reference goes away.
+// There are several caveats:
+// - Like all reference counting schemes, cycles lead to leaks.
+// - Each smart pointer is actually two pointers (8 bytes instead of 4).
+// - Every time a pointer is assigned, the entire list of pointers to that
+//   object is traversed.  This class is therefore NOT SUITABLE when there
+//   will often be more than two or three pointers to a particular object.
+// - References are only tracked as long as linked_ptr<> objects are copied.
+//   If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS
+//   will happen (double deletion).
+//
+// A good use of this class is storing object references in STL containers.
+// You can safely put linked_ptr<> in a vector<>.
+// Other uses may not be as good.
+//
+// Note: If you use an incomplete type with linked_ptr<>, the class
+// *containing* linked_ptr<> must have a constructor and destructor (even
+// if they do nothing!).
+//
+// Bill Gibbons suggested we use something like this.
+//
+// Thread Safety:
+//   Unlike other linked_ptr implementations, in this implementation
+//   a linked_ptr object is thread-safe in the sense that:
+//     - it's safe to copy linked_ptr objects concurrently,
+//     - it's safe to copy *from* a linked_ptr and read its underlying
+//       raw pointer (e.g. via get()) concurrently, and
+//     - it's safe to write to two linked_ptrs that point to the same
+//       shared object concurrently.
+// TODO(wan@google.com): rename this to safe_linked_ptr to avoid
+// confusion with normal linked_ptr.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include <gtest/internal/gtest-port.h>
+
+namespace testing {
+namespace internal {
+
+// Protects copying of all linked_ptr objects.
+GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex);
+
+// This is used internally by all instances of linked_ptr<>.  It needs to be
+// a non-template class because different types of linked_ptr<> can refer to
+// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)).
+// So, it needs to be possible for different types of linked_ptr to participate
+// in the same circular linked list, so we need a single class type here.
+//
+// DO NOT USE THIS CLASS DIRECTLY YOURSELF.  Use linked_ptr<T>.
+class linked_ptr_internal {
+ public:
+  // Create a new circle that includes only this instance.
+  void join_new() {
+    next_ = this;
+  }
+
+  // Many linked_ptr operations may change p.link_ for some linked_ptr
+  // variable p in the same circle as this object.  Therefore we need
+  // to prevent two such operations from occurring concurrently.
+  //
+  // Note that different types of linked_ptr objects can coexist in a
+  // circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and
+  // linked_ptr<Derived2>).  Therefore we must use a single mutex to
+  // protect all linked_ptr objects.  This can create serious
+  // contention in production code, but is acceptable in a testing
+  // framework.
+
+  // Join an existing circle.
+  // L < g_linked_ptr_mutex
+  void join(linked_ptr_internal const* ptr) {
+    MutexLock lock(&g_linked_ptr_mutex);
+
+    linked_ptr_internal const* p = ptr;
+    while (p->next_ != ptr) p = p->next_;
+    p->next_ = this;
+    next_ = ptr;
+  }
+
+  // Leave whatever circle we're part of.  Returns true if we were the
+  // last member of the circle.  Once this is done, you can join() another.
+  // L < g_linked_ptr_mutex
+  bool depart() {
+    MutexLock lock(&g_linked_ptr_mutex);
+
+    if (next_ == this) return true;
+    linked_ptr_internal const* p = next_;
+    while (p->next_ != this) p = p->next_;
+    p->next_ = next_;
+    return false;
+  }
+
+ private:
+  mutable linked_ptr_internal const* next_;
+};
+
+template <typename T>
+class linked_ptr {
+ public:
+  typedef T element_type;
+
+  // Take over ownership of a raw pointer.  This should happen as soon as
+  // possible after the object is created.
+  explicit linked_ptr(T* ptr = NULL) { capture(ptr); }
+  ~linked_ptr() { depart(); }
+
+  // Copy an existing linked_ptr<>, adding ourselves to the list of references.
+  template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); }
+  linked_ptr(linked_ptr const& ptr) {  // NOLINT
+    assert(&ptr != this);
+    copy(&ptr);
+  }
+
+  // Assignment releases the old value and acquires the new.
+  template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) {
+    depart();
+    copy(&ptr);
+    return *this;
+  }
+
+  linked_ptr& operator=(linked_ptr const& ptr) {
+    if (&ptr != this) {
+      depart();
+      copy(&ptr);
+    }
+    return *this;
+  }
+
+  // Smart pointer members.
+  void reset(T* ptr = NULL) {
+    depart();
+    capture(ptr);
+  }
+  T* get() const { return value_; }
+  T* operator->() const { return value_; }
+  T& operator*() const { return *value_; }
+  // Release ownership of the pointed object and returns it.
+  // Sole ownership by this linked_ptr object is required.
+  T* release() {
+    bool last = link_.depart();
+    (void) last;
+    assert(last);
+    T* v = value_;
+    value_ = NULL;
+    return v;
+  }
+
+  bool operator==(T* p) const { return value_ == p; }
+  bool operator!=(T* p) const { return value_ != p; }
+  template <typename U>
+  bool operator==(linked_ptr<U> const& ptr) const {
+    return value_ == ptr.get();
+  }
+  template <typename U>
+  bool operator!=(linked_ptr<U> const& ptr) const {
+    return value_ != ptr.get();
+  }
+
+ private:
+  template <typename U>
+  friend class linked_ptr;
+
+  T* value_;
+  linked_ptr_internal link_;
+
+  void depart() {
+    if (link_.depart()) delete value_;
+  }
+
+  void capture(T* ptr) {
+    value_ = ptr;
+    link_.join_new();
+  }
+
+  template <typename U> void copy(linked_ptr<U> const* ptr) {
+    value_ = ptr->get();
+    if (value_)
+      link_.join(&ptr->link_);
+    else
+      link_.join_new();
+  }
+};
+
+template<typename T> inline
+bool operator==(T* ptr, const linked_ptr<T>& x) {
+  return ptr == x.get();
+}
+
+template<typename T> inline
+bool operator!=(T* ptr, const linked_ptr<T>& x) {
+  return ptr != x.get();
+}
+
+// A function to convert T* into linked_ptr<T>
+// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation
+// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
+template <typename T>
+linked_ptr<T> make_linked_ptr(T* ptr) {
+  return linked_ptr<T>(ptr);
+}
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
diff --git a/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h
new file mode 100644
index 0000000..ab4ab56
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h
@@ -0,0 +1,4820 @@
+// This file was GENERATED by a script.  DO NOT EDIT BY HAND!!!
+
+// Copyright 2008 Google Inc.
+// All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: vladl@google.com (Vlad Losev)
+
+// Type and function utilities for implementing parameterized tests.
+// This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!
+//
+// Currently Google Test supports at most 50 arguments in Values,
+// and at most 10 arguments in Combine. Please contact
+// googletestframework@googlegroups.com if you need more.
+// Please note that the number of arguments to Combine is limited
+// by the maximum arity of the implementation of tr1::tuple which is
+// currently set at 10.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
+
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*.  Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
+#include <gtest/internal/gtest-param-util.h>
+#include <gtest/internal/gtest-port.h>
+
+#if GTEST_HAS_PARAM_TEST
+
+namespace testing {
+
+// Forward declarations of ValuesIn(), which is implemented in
+// include/gtest/gtest-param-test.h.
+template <typename ForwardIterator>
+internal::ParamGenerator<
+    typename ::std::iterator_traits<ForwardIterator>::value_type> ValuesIn(
+        ForwardIterator begin, ForwardIterator end);
+
+template <typename T, size_t N>
+internal::ParamGenerator<T> ValuesIn(const T (&array)[N]);
+
+template <class Container>
+internal::ParamGenerator<typename Container::value_type> ValuesIn(
+    const Container& container);
+
+namespace internal {
+
+// Used in the Values() function to provide polymorphic capabilities.
+template <typename T1>
+class ValueArray1 {
+ public:
+  explicit ValueArray1(T1 v1) : v1_(v1) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray1& other);
+
+  const T1 v1_;
+};
+
+template <typename T1, typename T2>
+class ValueArray2 {
+ public:
+  ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray2& other);
+
+  const T1 v1_;
+  const T2 v2_;
+};
+
+template <typename T1, typename T2, typename T3>
+class ValueArray3 {
+ public:
+  ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray3& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4>
+class ValueArray4 {
+ public:
+  ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray4& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+class ValueArray5 {
+ public:
+  ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray5& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6>
+class ValueArray6 {
+ public:
+  ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray6& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7>
+class ValueArray7 {
+ public:
+  ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray7& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8>
+class ValueArray8 {
+ public:
+  ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+      T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray8& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9>
+class ValueArray9 {
+ public:
+  ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
+      T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray9& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10>
+class ValueArray10 {
+ public:
+  ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray10& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11>
+class ValueArray11 {
+ public:
+  ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray11& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12>
+class ValueArray12 {
+ public:
+  ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray12& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13>
+class ValueArray13 {
+ public:
+  ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+      v12_(v12), v13_(v13) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray13& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14>
+class ValueArray14 {
+ public:
+  ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray14& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15>
+class ValueArray15 {
+ public:
+  ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray15& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16>
+class ValueArray16 {
+ public:
+  ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+      v16_(v16) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray16& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17>
+class ValueArray17 {
+ public:
+  ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
+      T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray17& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18>
+class ValueArray18 {
+ public:
+  ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray18& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19>
+class ValueArray19 {
+ public:
+  ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
+      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray19& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20>
+class ValueArray20 {
+ public:
+  ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
+      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
+      v19_(v19), v20_(v20) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray20& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21>
+class ValueArray21 {
+ public:
+  ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
+      v18_(v18), v19_(v19), v20_(v20), v21_(v21) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray21& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22>
+class ValueArray22 {
+ public:
+  ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray22& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23>
+class ValueArray23 {
+ public:
+  ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_,
+        v23_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray23& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24>
+class ValueArray24 {
+ public:
+  ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
+      v22_(v22), v23_(v23), v24_(v24) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray24& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25>
+class ValueArray25 {
+ public:
+  ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
+      T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray25& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26>
+class ValueArray26 {
+ public:
+  ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray26& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27>
+class ValueArray27 {
+ public:
+  ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
+      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
+      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
+      v26_(v26), v27_(v27) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray27& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28>
+class ValueArray28 {
+ public:
+  ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
+      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
+      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
+      v25_(v25), v26_(v26), v27_(v27), v28_(v28) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray28& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29>
+class ValueArray29 {
+ public:
+  ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
+      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
+      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray29& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30>
+class ValueArray30 {
+ public:
+  ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray30& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31>
+class ValueArray31 {
+ public:
+  ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30), v31_(v31) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray31& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32>
+class ValueArray32 {
+ public:
+  ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
+      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
+      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray32& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33>
+class ValueArray33 {
+ public:
+  ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32,
+      T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray33& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34>
+class ValueArray34 {
+ public:
+  ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33), v34_(v34) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray34& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35>
+class ValueArray35 {
+ public:
+  ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
+      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
+      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
+      v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),
+      v32_(v32), v33_(v33), v34_(v34), v35_(v35) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_,
+        v35_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray35& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36>
+class ValueArray36 {
+ public:
+  ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
+      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
+      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
+      v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),
+      v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray36& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37>
+class ValueArray37 {
+ public:
+  ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
+      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
+      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),
+      v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),
+      v36_(v36), v37_(v37) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray37& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38>
+class ValueArray38 {
+ public:
+  ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
+      v35_(v35), v36_(v36), v37_(v37), v38_(v38) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray38& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39>
+class ValueArray39 {
+ public:
+  ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
+      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray39& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40>
+class ValueArray40 {
+ public:
+  ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
+      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
+      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),
+      v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),
+      v40_(v40) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray40& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41>
+class ValueArray41 {
+ public:
+  ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40,
+      T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
+      v39_(v39), v40_(v40), v41_(v41) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray41& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42>
+class ValueArray42 {
+ public:
+  ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
+      v39_(v39), v40_(v40), v41_(v41), v42_(v42) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray42& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43>
+class ValueArray43 {
+ public:
+  ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
+      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
+      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
+      v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),
+      v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37),
+      v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray43& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44>
+class ValueArray44 {
+ public:
+  ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
+      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
+      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
+      v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),
+      v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36),
+      v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42),
+      v43_(v43), v44_(v44) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray44& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45>
+class ValueArray45 {
+ public:
+  ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
+      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
+      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),
+      v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),
+      v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41),
+      v42_(v42), v43_(v43), v44_(v44), v45_(v45) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray45& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46>
+class ValueArray46 {
+ public:
+  ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
+      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),
+      v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray46& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+  const T46 v46_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47>
+class ValueArray47 {
+ public:
+  ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
+      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),
+      v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46),
+      v47_(v47) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_,
+        v47_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray47& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+  const T46 v46_;
+  const T47 v47_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48>
+class ValueArray48 {
+ public:
+  ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
+      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
+      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),
+      v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),
+      v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45),
+      v46_(v46), v47_(v47), v48_(v48) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,
+        v48_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray48& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+  const T46 v46_;
+  const T47 v47_;
+  const T48 v48_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49>
+class ValueArray49 {
+ public:
+  ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48,
+      T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
+      v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),
+      v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,
+        v48_, v49_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray49& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+  const T46 v46_;
+  const T47 v47_;
+  const T48 v48_;
+  const T49 v49_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49, typename T50>
+class ValueArray50 {
+ public:
+  ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49,
+      T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
+      v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),
+      v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,
+        v48_, v49_, v50_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray50& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+  const T46 v46_;
+  const T47 v47_;
+  const T48 v48_;
+  const T49 v49_;
+  const T50 v50_;
+};
+
+#if GTEST_HAS_COMBINE
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Generates values from the Cartesian product of values produced
+// by the argument generators.
+//
+template <typename T1, typename T2>
+class CartesianProductGenerator2
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2> ParamType;
+
+  CartesianProductGenerator2(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2)
+      : g1_(g1), g2_(g2) {}
+  virtual ~CartesianProductGenerator2() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current2_;
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator2::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator2& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+};  // class CartesianProductGenerator2
+
+
+template <typename T1, typename T2, typename T3>
+class CartesianProductGenerator3
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3> ParamType;
+
+  CartesianProductGenerator3(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3)
+      : g1_(g1), g2_(g2), g3_(g3) {}
+  virtual ~CartesianProductGenerator3() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current3_;
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator3::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator3& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+};  // class CartesianProductGenerator3
+
+
+template <typename T1, typename T2, typename T3, typename T4>
+class CartesianProductGenerator4
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4> ParamType;
+
+  CartesianProductGenerator4(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}
+  virtual ~CartesianProductGenerator4() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current4_;
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator4::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator4& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+};  // class CartesianProductGenerator4
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+class CartesianProductGenerator5
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5> ParamType;
+
+  CartesianProductGenerator5(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}
+  virtual ~CartesianProductGenerator5() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current5_;
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator5::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator5& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+};  // class CartesianProductGenerator5
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6>
+class CartesianProductGenerator6
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5,
+        T6> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> ParamType;
+
+  CartesianProductGenerator6(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+      const ParamGenerator<T6>& g6)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}
+  virtual ~CartesianProductGenerator6() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5,
+      const ParamGenerator<T6>& g6,
+      const typename ParamGenerator<T6>::iterator& current6)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+          begin6_(g6.begin()), end6_(g6.end()), current6_(current6)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current6_;
+      if (current6_ == end6_) {
+        current6_ = begin6_;
+        ++current5_;
+      }
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_ &&
+          current6_ == typed_other->current6_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_),
+        begin6_(other.begin6_),
+        end6_(other.end6_),
+        current6_(other.current6_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_, *current6_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_ ||
+          current6_ == end6_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    const typename ParamGenerator<T6>::iterator begin6_;
+    const typename ParamGenerator<T6>::iterator end6_;
+    typename ParamGenerator<T6>::iterator current6_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator6::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator6& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+  const ParamGenerator<T6> g6_;
+};  // class CartesianProductGenerator6
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7>
+class CartesianProductGenerator7
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+        T7> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> ParamType;
+
+  CartesianProductGenerator7(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}
+  virtual ~CartesianProductGenerator7() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
+        g7_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5,
+      const ParamGenerator<T6>& g6,
+      const typename ParamGenerator<T6>::iterator& current6,
+      const ParamGenerator<T7>& g7,
+      const typename ParamGenerator<T7>::iterator& current7)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
+          begin7_(g7.begin()), end7_(g7.end()), current7_(current7)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current7_;
+      if (current7_ == end7_) {
+        current7_ = begin7_;
+        ++current6_;
+      }
+      if (current6_ == end6_) {
+        current6_ = begin6_;
+        ++current5_;
+      }
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_ &&
+          current6_ == typed_other->current6_ &&
+          current7_ == typed_other->current7_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_),
+        begin6_(other.begin6_),
+        end6_(other.end6_),
+        current6_(other.current6_),
+        begin7_(other.begin7_),
+        end7_(other.end7_),
+        current7_(other.current7_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_, *current6_, *current7_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_ ||
+          current6_ == end6_ ||
+          current7_ == end7_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    const typename ParamGenerator<T6>::iterator begin6_;
+    const typename ParamGenerator<T6>::iterator end6_;
+    typename ParamGenerator<T6>::iterator current6_;
+    const typename ParamGenerator<T7>::iterator begin7_;
+    const typename ParamGenerator<T7>::iterator end7_;
+    typename ParamGenerator<T7>::iterator current7_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator7::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator7& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+  const ParamGenerator<T6> g6_;
+  const ParamGenerator<T7> g7_;
+};  // class CartesianProductGenerator7
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8>
+class CartesianProductGenerator8
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+        T7, T8> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> ParamType;
+
+  CartesianProductGenerator8(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
+      const ParamGenerator<T8>& g8)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),
+          g8_(g8) {}
+  virtual ~CartesianProductGenerator8() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
+        g7_.begin(), g8_, g8_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
+        g8_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5,
+      const ParamGenerator<T6>& g6,
+      const typename ParamGenerator<T6>::iterator& current6,
+      const ParamGenerator<T7>& g7,
+      const typename ParamGenerator<T7>::iterator& current7,
+      const ParamGenerator<T8>& g8,
+      const typename ParamGenerator<T8>::iterator& current8)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
+          begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
+          begin8_(g8.begin()), end8_(g8.end()), current8_(current8)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current8_;
+      if (current8_ == end8_) {
+        current8_ = begin8_;
+        ++current7_;
+      }
+      if (current7_ == end7_) {
+        current7_ = begin7_;
+        ++current6_;
+      }
+      if (current6_ == end6_) {
+        current6_ = begin6_;
+        ++current5_;
+      }
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_ &&
+          current6_ == typed_other->current6_ &&
+          current7_ == typed_other->current7_ &&
+          current8_ == typed_other->current8_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_),
+        begin6_(other.begin6_),
+        end6_(other.end6_),
+        current6_(other.current6_),
+        begin7_(other.begin7_),
+        end7_(other.end7_),
+        current7_(other.current7_),
+        begin8_(other.begin8_),
+        end8_(other.end8_),
+        current8_(other.current8_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_, *current6_, *current7_, *current8_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_ ||
+          current6_ == end6_ ||
+          current7_ == end7_ ||
+          current8_ == end8_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    const typename ParamGenerator<T6>::iterator begin6_;
+    const typename ParamGenerator<T6>::iterator end6_;
+    typename ParamGenerator<T6>::iterator current6_;
+    const typename ParamGenerator<T7>::iterator begin7_;
+    const typename ParamGenerator<T7>::iterator end7_;
+    typename ParamGenerator<T7>::iterator current7_;
+    const typename ParamGenerator<T8>::iterator begin8_;
+    const typename ParamGenerator<T8>::iterator end8_;
+    typename ParamGenerator<T8>::iterator current8_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator8::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator8& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+  const ParamGenerator<T6> g6_;
+  const ParamGenerator<T7> g7_;
+  const ParamGenerator<T8> g8_;
+};  // class CartesianProductGenerator8
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9>
+class CartesianProductGenerator9
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+        T7, T8, T9> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9> ParamType;
+
+  CartesianProductGenerator9(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
+      const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
+          g9_(g9) {}
+  virtual ~CartesianProductGenerator9() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
+        g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
+        g8_.end(), g9_, g9_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5,
+      const ParamGenerator<T6>& g6,
+      const typename ParamGenerator<T6>::iterator& current6,
+      const ParamGenerator<T7>& g7,
+      const typename ParamGenerator<T7>::iterator& current7,
+      const ParamGenerator<T8>& g8,
+      const typename ParamGenerator<T8>::iterator& current8,
+      const ParamGenerator<T9>& g9,
+      const typename ParamGenerator<T9>::iterator& current9)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
+          begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
+          begin8_(g8.begin()), end8_(g8.end()), current8_(current8),
+          begin9_(g9.begin()), end9_(g9.end()), current9_(current9)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current9_;
+      if (current9_ == end9_) {
+        current9_ = begin9_;
+        ++current8_;
+      }
+      if (current8_ == end8_) {
+        current8_ = begin8_;
+        ++current7_;
+      }
+      if (current7_ == end7_) {
+        current7_ = begin7_;
+        ++current6_;
+      }
+      if (current6_ == end6_) {
+        current6_ = begin6_;
+        ++current5_;
+      }
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_ &&
+          current6_ == typed_other->current6_ &&
+          current7_ == typed_other->current7_ &&
+          current8_ == typed_other->current8_ &&
+          current9_ == typed_other->current9_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_),
+        begin6_(other.begin6_),
+        end6_(other.end6_),
+        current6_(other.current6_),
+        begin7_(other.begin7_),
+        end7_(other.end7_),
+        current7_(other.current7_),
+        begin8_(other.begin8_),
+        end8_(other.end8_),
+        current8_(other.current8_),
+        begin9_(other.begin9_),
+        end9_(other.end9_),
+        current9_(other.current9_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_, *current6_, *current7_, *current8_,
+            *current9_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_ ||
+          current6_ == end6_ ||
+          current7_ == end7_ ||
+          current8_ == end8_ ||
+          current9_ == end9_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    const typename ParamGenerator<T6>::iterator begin6_;
+    const typename ParamGenerator<T6>::iterator end6_;
+    typename ParamGenerator<T6>::iterator current6_;
+    const typename ParamGenerator<T7>::iterator begin7_;
+    const typename ParamGenerator<T7>::iterator end7_;
+    typename ParamGenerator<T7>::iterator current7_;
+    const typename ParamGenerator<T8>::iterator begin8_;
+    const typename ParamGenerator<T8>::iterator end8_;
+    typename ParamGenerator<T8>::iterator current8_;
+    const typename ParamGenerator<T9>::iterator begin9_;
+    const typename ParamGenerator<T9>::iterator end9_;
+    typename ParamGenerator<T9>::iterator current9_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator9::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator9& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+  const ParamGenerator<T6> g6_;
+  const ParamGenerator<T7> g7_;
+  const ParamGenerator<T8> g8_;
+  const ParamGenerator<T9> g9_;
+};  // class CartesianProductGenerator9
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10>
+class CartesianProductGenerator10
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+        T7, T8, T9, T10> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ParamType;
+
+  CartesianProductGenerator10(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
+      const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9,
+      const ParamGenerator<T10>& g10)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
+          g9_(g9), g10_(g10) {}
+  virtual ~CartesianProductGenerator10() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
+        g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
+        g8_.end(), g9_, g9_.end(), g10_, g10_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5,
+      const ParamGenerator<T6>& g6,
+      const typename ParamGenerator<T6>::iterator& current6,
+      const ParamGenerator<T7>& g7,
+      const typename ParamGenerator<T7>::iterator& current7,
+      const ParamGenerator<T8>& g8,
+      const typename ParamGenerator<T8>::iterator& current8,
+      const ParamGenerator<T9>& g9,
+      const typename ParamGenerator<T9>::iterator& current9,
+      const ParamGenerator<T10>& g10,
+      const typename ParamGenerator<T10>::iterator& current10)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
+          begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
+          begin8_(g8.begin()), end8_(g8.end()), current8_(current8),
+          begin9_(g9.begin()), end9_(g9.end()), current9_(current9),
+          begin10_(g10.begin()), end10_(g10.end()), current10_(current10)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current10_;
+      if (current10_ == end10_) {
+        current10_ = begin10_;
+        ++current9_;
+      }
+      if (current9_ == end9_) {
+        current9_ = begin9_;
+        ++current8_;
+      }
+      if (current8_ == end8_) {
+        current8_ = begin8_;
+        ++current7_;
+      }
+      if (current7_ == end7_) {
+        current7_ = begin7_;
+        ++current6_;
+      }
+      if (current6_ == end6_) {
+        current6_ = begin6_;
+        ++current5_;
+      }
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_ &&
+          current6_ == typed_other->current6_ &&
+          current7_ == typed_other->current7_ &&
+          current8_ == typed_other->current8_ &&
+          current9_ == typed_other->current9_ &&
+          current10_ == typed_other->current10_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_),
+        begin6_(other.begin6_),
+        end6_(other.end6_),
+        current6_(other.current6_),
+        begin7_(other.begin7_),
+        end7_(other.end7_),
+        current7_(other.current7_),
+        begin8_(other.begin8_),
+        end8_(other.end8_),
+        current8_(other.current8_),
+        begin9_(other.begin9_),
+        end9_(other.end9_),
+        current9_(other.current9_),
+        begin10_(other.begin10_),
+        end10_(other.end10_),
+        current10_(other.current10_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_, *current6_, *current7_, *current8_,
+            *current9_, *current10_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_ ||
+          current6_ == end6_ ||
+          current7_ == end7_ ||
+          current8_ == end8_ ||
+          current9_ == end9_ ||
+          current10_ == end10_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    const typename ParamGenerator<T6>::iterator begin6_;
+    const typename ParamGenerator<T6>::iterator end6_;
+    typename ParamGenerator<T6>::iterator current6_;
+    const typename ParamGenerator<T7>::iterator begin7_;
+    const typename ParamGenerator<T7>::iterator end7_;
+    typename ParamGenerator<T7>::iterator current7_;
+    const typename ParamGenerator<T8>::iterator begin8_;
+    const typename ParamGenerator<T8>::iterator end8_;
+    typename ParamGenerator<T8>::iterator current8_;
+    const typename ParamGenerator<T9>::iterator begin9_;
+    const typename ParamGenerator<T9>::iterator end9_;
+    typename ParamGenerator<T9>::iterator current9_;
+    const typename ParamGenerator<T10>::iterator begin10_;
+    const typename ParamGenerator<T10>::iterator end10_;
+    typename ParamGenerator<T10>::iterator current10_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator10::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator10& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+  const ParamGenerator<T6> g6_;
+  const ParamGenerator<T7> g7_;
+  const ParamGenerator<T8> g8_;
+  const ParamGenerator<T9> g9_;
+  const ParamGenerator<T10> g10_;
+};  // class CartesianProductGenerator10
+
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Helper classes providing Combine() with polymorphic features. They allow
+// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is
+// convertible to U.
+//
+template <class Generator1, class Generator2>
+class CartesianProductHolder2 {
+ public:
+CartesianProductHolder2(const Generator1& g1, const Generator2& g2)
+      : g1_(g1), g2_(g2) {}
+  template <typename T1, typename T2>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2> >(
+        new CartesianProductGenerator2<T1, T2>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder2& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+};  // class CartesianProductHolder2
+
+template <class Generator1, class Generator2, class Generator3>
+class CartesianProductHolder3 {
+ public:
+CartesianProductHolder3(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3)
+      : g1_(g1), g2_(g2), g3_(g3) {}
+  template <typename T1, typename T2, typename T3>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >(
+        new CartesianProductGenerator3<T1, T2, T3>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder3& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+};  // class CartesianProductHolder3
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4>
+class CartesianProductHolder4 {
+ public:
+CartesianProductHolder4(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}
+  template <typename T1, typename T2, typename T3, typename T4>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >(
+        new CartesianProductGenerator4<T1, T2, T3, T4>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder4& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+};  // class CartesianProductHolder4
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5>
+class CartesianProductHolder5 {
+ public:
+CartesianProductHolder5(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >(
+        new CartesianProductGenerator5<T1, T2, T3, T4, T5>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder5& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+};  // class CartesianProductHolder5
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5, class Generator6>
+class CartesianProductHolder6 {
+ public:
+CartesianProductHolder6(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5,
+    const Generator6& g6)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+      typename T6>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >(
+        new CartesianProductGenerator6<T1, T2, T3, T4, T5, T6>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_),
+        static_cast<ParamGenerator<T6> >(g6_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder6& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+  const Generator6 g6_;
+};  // class CartesianProductHolder6
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5, class Generator6, class Generator7>
+class CartesianProductHolder7 {
+ public:
+CartesianProductHolder7(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5,
+    const Generator6& g6, const Generator7& g7)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+      typename T6, typename T7>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+      T7> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> >(
+        new CartesianProductGenerator7<T1, T2, T3, T4, T5, T6, T7>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_),
+        static_cast<ParamGenerator<T6> >(g6_),
+        static_cast<ParamGenerator<T7> >(g7_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder7& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+  const Generator6 g6_;
+  const Generator7 g7_;
+};  // class CartesianProductHolder7
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5, class Generator6, class Generator7,
+    class Generator8>
+class CartesianProductHolder8 {
+ public:
+CartesianProductHolder8(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5,
+    const Generator6& g6, const Generator7& g7, const Generator8& g8)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),
+          g8_(g8) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+      typename T6, typename T7, typename T8>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7,
+      T8> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> >(
+        new CartesianProductGenerator8<T1, T2, T3, T4, T5, T6, T7, T8>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_),
+        static_cast<ParamGenerator<T6> >(g6_),
+        static_cast<ParamGenerator<T7> >(g7_),
+        static_cast<ParamGenerator<T8> >(g8_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder8& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+  const Generator6 g6_;
+  const Generator7 g7_;
+  const Generator8 g8_;
+};  // class CartesianProductHolder8
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5, class Generator6, class Generator7,
+    class Generator8, class Generator9>
+class CartesianProductHolder9 {
+ public:
+CartesianProductHolder9(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5,
+    const Generator6& g6, const Generator7& g7, const Generator8& g8,
+    const Generator9& g9)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
+          g9_(g9) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+      typename T6, typename T7, typename T8, typename T9>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
+      T9> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
+        T9> >(
+        new CartesianProductGenerator9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_),
+        static_cast<ParamGenerator<T6> >(g6_),
+        static_cast<ParamGenerator<T7> >(g7_),
+        static_cast<ParamGenerator<T8> >(g8_),
+        static_cast<ParamGenerator<T9> >(g9_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder9& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+  const Generator6 g6_;
+  const Generator7 g7_;
+  const Generator8 g8_;
+  const Generator9 g9_;
+};  // class CartesianProductHolder9
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5, class Generator6, class Generator7,
+    class Generator8, class Generator9, class Generator10>
+class CartesianProductHolder10 {
+ public:
+CartesianProductHolder10(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5,
+    const Generator6& g6, const Generator7& g7, const Generator8& g8,
+    const Generator9& g9, const Generator10& g10)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
+          g9_(g9), g10_(g10) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+      typename T6, typename T7, typename T8, typename T9, typename T10>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
+      T9, T10> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
+        T9, T10> >(
+        new CartesianProductGenerator10<T1, T2, T3, T4, T5, T6, T7, T8, T9,
+            T10>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_),
+        static_cast<ParamGenerator<T6> >(g6_),
+        static_cast<ParamGenerator<T7> >(g7_),
+        static_cast<ParamGenerator<T8> >(g8_),
+        static_cast<ParamGenerator<T9> >(g9_),
+        static_cast<ParamGenerator<T10> >(g10_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder10& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+  const Generator6 g6_;
+  const Generator7 g7_;
+  const Generator8 g8_;
+  const Generator9 g9_;
+  const Generator10 g10_;
+};  // class CartesianProductHolder10
+
+#endif  // GTEST_HAS_COMBINE
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  //  GTEST_HAS_PARAM_TEST
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
diff --git a/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h
new file mode 100644
index 0000000..0cbb58c
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h
@@ -0,0 +1,619 @@
+// Copyright 2008 Google Inc.
+// All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: vladl@google.com (Vlad Losev)
+
+// Type and function utilities for implementing parameterized tests.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
+
+#include <iterator>
+#include <utility>
+#include <vector>
+
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*.  Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
+#include <gtest/internal/gtest-internal.h>
+#include <gtest/internal/gtest-linked_ptr.h>
+#include <gtest/internal/gtest-port.h>
+
+#if GTEST_HAS_PARAM_TEST
+
+namespace testing {
+namespace internal {
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Outputs a message explaining invalid registration of different
+// fixture class for the same test case. This may happen when
+// TEST_P macro is used to define two tests with the same name
+// but in different namespaces.
+GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name,
+                                          const char* file, int line);
+
+template <typename> class ParamGeneratorInterface;
+template <typename> class ParamGenerator;
+
+// Interface for iterating over elements provided by an implementation
+// of ParamGeneratorInterface<T>.
+template <typename T>
+class ParamIteratorInterface {
+ public:
+  virtual ~ParamIteratorInterface() {}
+  // A pointer to the base generator instance.
+  // Used only for the purposes of iterator comparison
+  // to make sure that two iterators belong to the same generator.
+  virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;
+  // Advances iterator to point to the next element
+  // provided by the generator. The caller is responsible
+  // for not calling Advance() on an iterator equal to
+  // BaseGenerator()->End().
+  virtual void Advance() = 0;
+  // Clones the iterator object. Used for implementing copy semantics
+  // of ParamIterator<T>.
+  virtual ParamIteratorInterface* Clone() const = 0;
+  // Dereferences the current iterator and provides (read-only) access
+  // to the pointed value. It is the caller's responsibility not to call
+  // Current() on an iterator equal to BaseGenerator()->End().
+  // Used for implementing ParamGenerator<T>::operator*().
+  virtual const T* Current() const = 0;
+  // Determines whether the given iterator and other point to the same
+  // element in the sequence generated by the generator.
+  // Used for implementing ParamGenerator<T>::operator==().
+  virtual bool Equals(const ParamIteratorInterface& other) const = 0;
+};
+
+// Class iterating over elements provided by an implementation of
+// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
+// and implements the const forward iterator concept.
+template <typename T>
+class ParamIterator {
+ public:
+  typedef T value_type;
+  typedef const T& reference;
+  typedef ptrdiff_t difference_type;
+
+  // ParamIterator assumes ownership of the impl_ pointer.
+  ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}
+  ParamIterator& operator=(const ParamIterator& other) {
+    if (this != &other)
+      impl_.reset(other.impl_->Clone());
+    return *this;
+  }
+
+  const T& operator*() const { return *impl_->Current(); }
+  const T* operator->() const { return impl_->Current(); }
+  // Prefix version of operator++.
+  ParamIterator& operator++() {
+    impl_->Advance();
+    return *this;
+  }
+  // Postfix version of operator++.
+  ParamIterator operator++(int /*unused*/) {
+    ParamIteratorInterface<T>* clone = impl_->Clone();
+    impl_->Advance();
+    return ParamIterator(clone);
+  }
+  bool operator==(const ParamIterator& other) const {
+    return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
+  }
+  bool operator!=(const ParamIterator& other) const {
+    return !(*this == other);
+  }
+
+ private:
+  friend class ParamGenerator<T>;
+  explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
+  scoped_ptr<ParamIteratorInterface<T> > impl_;
+};
+
+// ParamGeneratorInterface<T> is the binary interface to access generators
+// defined in other translation units.
+template <typename T>
+class ParamGeneratorInterface {
+ public:
+  typedef T ParamType;
+
+  virtual ~ParamGeneratorInterface() {}
+
+  // Generator interface definition
+  virtual ParamIteratorInterface<T>* Begin() const = 0;
+  virtual ParamIteratorInterface<T>* End() const = 0;
+};
+
+// Wraps ParamGeneratorInterface<T> and provides general generator syntax
+// compatible with the STL Container concept.
+// This class implements copy initialization semantics and the contained
+// ParamGeneratorInterface<T> instance is shared among all copies
+// of the original object. This is possible because that instance is immutable.
+template<typename T>
+class ParamGenerator {
+ public:
+  typedef ParamIterator<T> iterator;
+
+  explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}
+  ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}
+
+  ParamGenerator& operator=(const ParamGenerator& other) {
+    impl_ = other.impl_;
+    return *this;
+  }
+
+  iterator begin() const { return iterator(impl_->Begin()); }
+  iterator end() const { return iterator(impl_->End()); }
+
+ private:
+  ::testing::internal::linked_ptr<const ParamGeneratorInterface<T> > impl_;
+};
+
+// Generates values from a range of two comparable values. Can be used to
+// generate sequences of user-defined types that implement operator+() and
+// operator<().
+// This class is used in the Range() function.
+template <typename T, typename IncrementT>
+class RangeGenerator : public ParamGeneratorInterface<T> {
+ public:
+  RangeGenerator(T begin, T end, IncrementT step)
+      : begin_(begin), end_(end),
+        step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
+  virtual ~RangeGenerator() {}
+
+  virtual ParamIteratorInterface<T>* Begin() const {
+    return new Iterator(this, begin_, 0, step_);
+  }
+  virtual ParamIteratorInterface<T>* End() const {
+    return new Iterator(this, end_, end_index_, step_);
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<T> {
+   public:
+    Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
+             IncrementT step)
+        : base_(base), value_(value), index_(index), step_(step) {}
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
+      return base_;
+    }
+    virtual void Advance() {
+      value_ = value_ + step_;
+      index_++;
+    }
+    virtual ParamIteratorInterface<T>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const T* Current() const { return &value_; }
+    virtual bool Equals(const ParamIteratorInterface<T>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const int other_index =
+          CheckedDowncastToActualType<const Iterator>(&other)->index_;
+      return index_ == other_index;
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : ParamIteratorInterface<T>(),
+          base_(other.base_), value_(other.value_), index_(other.index_),
+          step_(other.step_) {}
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<T>* const base_;
+    T value_;
+    int index_;
+    const IncrementT step_;
+  };  // class RangeGenerator::Iterator
+
+  static int CalculateEndIndex(const T& begin,
+                               const T& end,
+                               const IncrementT& step) {
+    int end_index = 0;
+    for (T i = begin; i < end; i = i + step)
+      end_index++;
+    return end_index;
+  }
+
+  // No implementation - assignment is unsupported.
+  void operator=(const RangeGenerator& other);
+
+  const T begin_;
+  const T end_;
+  const IncrementT step_;
+  // The index for the end() iterator. All the elements in the generated
+  // sequence are indexed (0-based) to aid iterator comparison.
+  const int end_index_;
+};  // class RangeGenerator
+
+
+// Generates values from a pair of STL-style iterators. Used in the
+// ValuesIn() function. The elements are copied from the source range
+// since the source can be located on the stack, and the generator
+// is likely to persist beyond that stack frame.
+template <typename T>
+class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
+ public:
+  template <typename ForwardIterator>
+  ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
+      : container_(begin, end) {}
+  virtual ~ValuesInIteratorRangeGenerator() {}
+
+  virtual ParamIteratorInterface<T>* Begin() const {
+    return new Iterator(this, container_.begin());
+  }
+  virtual ParamIteratorInterface<T>* End() const {
+    return new Iterator(this, container_.end());
+  }
+
+ private:
+  typedef typename ::std::vector<T> ContainerType;
+
+  class Iterator : public ParamIteratorInterface<T> {
+   public:
+    Iterator(const ParamGeneratorInterface<T>* base,
+             typename ContainerType::const_iterator iterator)
+        :  base_(base), iterator_(iterator) {}
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
+      return base_;
+    }
+    virtual void Advance() {
+      ++iterator_;
+      value_.reset();
+    }
+    virtual ParamIteratorInterface<T>* Clone() const {
+      return new Iterator(*this);
+    }
+    // We need to use cached value referenced by iterator_ because *iterator_
+    // can return a temporary object (and of type other then T), so just
+    // having "return &*iterator_;" doesn't work.
+    // value_ is updated here and not in Advance() because Advance()
+    // can advance iterator_ beyond the end of the range, and we cannot
+    // detect that fact. The client code, on the other hand, is
+    // responsible for not calling Current() on an out-of-range iterator.
+    virtual const T* Current() const {
+      if (value_.get() == NULL)
+        value_.reset(new T(*iterator_));
+      return value_.get();
+    }
+    virtual bool Equals(const ParamIteratorInterface<T>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      return iterator_ ==
+          CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
+    }
+
+   private:
+    Iterator(const Iterator& other)
+          // The explicit constructor call suppresses a false warning
+          // emitted by gcc when supplied with the -Wextra option.
+        : ParamIteratorInterface<T>(),
+          base_(other.base_),
+          iterator_(other.iterator_) {}
+
+    const ParamGeneratorInterface<T>* const base_;
+    typename ContainerType::const_iterator iterator_;
+    // A cached value of *iterator_. We keep it here to allow access by
+    // pointer in the wrapping iterator's operator->().
+    // value_ needs to be mutable to be accessed in Current().
+    // Use of scoped_ptr helps manage cached value's lifetime,
+    // which is bound by the lifespan of the iterator itself.
+    mutable scoped_ptr<const T> value_;
+  };  // class ValuesInIteratorRangeGenerator::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const ValuesInIteratorRangeGenerator& other);
+
+  const ContainerType container_;
+};  // class ValuesInIteratorRangeGenerator
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Stores a parameter value and later creates tests parameterized with that
+// value.
+template <class TestClass>
+class ParameterizedTestFactory : public TestFactoryBase {
+ public:
+  typedef typename TestClass::ParamType ParamType;
+  explicit ParameterizedTestFactory(ParamType parameter) :
+      parameter_(parameter) {}
+  virtual Test* CreateTest() {
+    TestClass::SetParam(&parameter_);
+    return new TestClass();
+  }
+
+ private:
+  const ParamType parameter_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory);
+};
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// TestMetaFactoryBase is a base class for meta-factories that create
+// test factories for passing into MakeAndRegisterTestInfo function.
+template <class ParamType>
+class TestMetaFactoryBase {
+ public:
+  virtual ~TestMetaFactoryBase() {}
+
+  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;
+};
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// TestMetaFactory creates test factories for passing into
+// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
+// ownership of test factory pointer, same factory object cannot be passed
+// into that method twice. But ParameterizedTestCaseInfo is going to call
+// it for each Test/Parameter value combination. Thus it needs meta factory
+// creator class.
+template <class TestCase>
+class TestMetaFactory
+    : public TestMetaFactoryBase<typename TestCase::ParamType> {
+ public:
+  typedef typename TestCase::ParamType ParamType;
+
+  TestMetaFactory() {}
+
+  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) {
+    return new ParameterizedTestFactory<TestCase>(parameter);
+  }
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory);
+};
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// ParameterizedTestCaseInfoBase is a generic interface
+// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase
+// accumulates test information provided by TEST_P macro invocations
+// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations
+// and uses that information to register all resulting test instances
+// in RegisterTests method. The ParameterizeTestCaseRegistry class holds
+// a collection of pointers to the ParameterizedTestCaseInfo objects
+// and calls RegisterTests() on each of them when asked.
+class ParameterizedTestCaseInfoBase {
+ public:
+  virtual ~ParameterizedTestCaseInfoBase() {}
+
+  // Base part of test case name for display purposes.
+  virtual const String& GetTestCaseName() const = 0;
+  // Test case id to verify identity.
+  virtual TypeId GetTestCaseTypeId() const = 0;
+  // UnitTest class invokes this method to register tests in this
+  // test case right before running them in RUN_ALL_TESTS macro.
+  // This method should not be called more then once on any single
+  // instance of a ParameterizedTestCaseInfoBase derived class.
+  virtual void RegisterTests() = 0;
+
+ protected:
+  ParameterizedTestCaseInfoBase() {}
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase);
+};
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P
+// macro invocations for a particular test case and generators
+// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that
+// test case. It registers tests with all values generated by all
+// generators when asked.
+template <class TestCase>
+class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
+ public:
+  // ParamType and GeneratorCreationFunc are private types but are required
+  // for declarations of public methods AddTestPattern() and
+  // AddTestCaseInstantiation().
+  typedef typename TestCase::ParamType ParamType;
+  // A function that returns an instance of appropriate generator type.
+  typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
+
+  explicit ParameterizedTestCaseInfo(const char* name)
+      : test_case_name_(name) {}
+
+  // Test case base name for display purposes.
+  virtual const String& GetTestCaseName() const { return test_case_name_; }
+  // Test case id to verify identity.
+  virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); }
+  // TEST_P macro uses AddTestPattern() to record information
+  // about a single test in a LocalTestInfo structure.
+  // test_case_name is the base name of the test case (without invocation
+  // prefix). test_base_name is the name of an individual test without
+  // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
+  // test case base name and DoBar is test base name.
+  void AddTestPattern(const char* test_case_name,
+                      const char* test_base_name,
+                      TestMetaFactoryBase<ParamType>* meta_factory) {
+    tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name,
+                                                       test_base_name,
+                                                       meta_factory)));
+  }
+  // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information
+  // about a generator.
+  int AddTestCaseInstantiation(const char* instantiation_name,
+                               GeneratorCreationFunc* func,
+                               const char* /* file */,
+                               int /* line */) {
+    instantiations_.push_back(::std::make_pair(instantiation_name, func));
+    return 0;  // Return value used only to run this method in namespace scope.
+  }
+  // UnitTest class invokes this method to register tests in this test case
+  // test cases right before running tests in RUN_ALL_TESTS macro.
+  // This method should not be called more then once on any single
+  // instance of a ParameterizedTestCaseInfoBase derived class.
+  // UnitTest has a guard to prevent from calling this method more then once.
+  virtual void RegisterTests() {
+    for (typename TestInfoContainer::iterator test_it = tests_.begin();
+         test_it != tests_.end(); ++test_it) {
+      linked_ptr<TestInfo> test_info = *test_it;
+      for (typename InstantiationContainer::iterator gen_it =
+               instantiations_.begin(); gen_it != instantiations_.end();
+               ++gen_it) {
+        const String& instantiation_name = gen_it->first;
+        ParamGenerator<ParamType> generator((*gen_it->second)());
+
+        Message test_case_name_stream;
+        if ( !instantiation_name.empty() )
+          test_case_name_stream << instantiation_name.c_str() << "/";
+        test_case_name_stream << test_info->test_case_base_name.c_str();
+
+        int i = 0;
+        for (typename ParamGenerator<ParamType>::iterator param_it =
+                 generator.begin();
+             param_it != generator.end(); ++param_it, ++i) {
+          Message test_name_stream;
+          test_name_stream << test_info->test_base_name.c_str() << "/" << i;
+          ::testing::internal::MakeAndRegisterTestInfo(
+              test_case_name_stream.GetString().c_str(),
+              test_name_stream.GetString().c_str(),
+              "",  // test_case_comment
+              "",  // comment; TODO(vladl@google.com): provide parameter value
+                   //                                  representation.
+              GetTestCaseTypeId(),
+              TestCase::SetUpTestCase,
+              TestCase::TearDownTestCase,
+              test_info->test_meta_factory->CreateTestFactory(*param_it));
+        }  // for param_it
+      }  // for gen_it
+    }  // for test_it
+  }  // RegisterTests
+
+ private:
+  // LocalTestInfo structure keeps information about a single test registered
+  // with TEST_P macro.
+  struct TestInfo {
+    TestInfo(const char* a_test_case_base_name,
+             const char* a_test_base_name,
+             TestMetaFactoryBase<ParamType>* a_test_meta_factory) :
+        test_case_base_name(a_test_case_base_name),
+        test_base_name(a_test_base_name),
+        test_meta_factory(a_test_meta_factory) {}
+
+    const String test_case_base_name;
+    const String test_base_name;
+    const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
+  };
+  typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer;
+  // Keeps pairs of <Instantiation name, Sequence generator creation function>
+  // received from INSTANTIATE_TEST_CASE_P macros.
+  typedef ::std::vector<std::pair<String, GeneratorCreationFunc*> >
+      InstantiationContainer;
+
+  const String test_case_name_;
+  TestInfoContainer tests_;
+  InstantiationContainer instantiations_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo);
+};  // class ParameterizedTestCaseInfo
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase
+// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P
+// macros use it to locate their corresponding ParameterizedTestCaseInfo
+// descriptors.
+class ParameterizedTestCaseRegistry {
+ public:
+  ParameterizedTestCaseRegistry() {}
+  ~ParameterizedTestCaseRegistry() {
+    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
+         it != test_case_infos_.end(); ++it) {
+      delete *it;
+    }
+  }
+
+  // Looks up or creates and returns a structure containing information about
+  // tests and instantiations of a particular test case.
+  template <class TestCase>
+  ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
+      const char* test_case_name,
+      const char* file,
+      int line) {
+    ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;
+    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
+         it != test_case_infos_.end(); ++it) {
+      if ((*it)->GetTestCaseName() == test_case_name) {
+        if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) {
+          // Complain about incorrect usage of Google Test facilities
+          // and terminate the program since we cannot guaranty correct
+          // test case setup and tear-down in this case.
+          ReportInvalidTestCaseType(test_case_name,  file, line);
+          abort();
+        } else {
+          // At this point we are sure that the object we found is of the same
+          // type we are looking for, so we downcast it to that type
+          // without further checks.
+          typed_test_info = CheckedDowncastToActualType<
+              ParameterizedTestCaseInfo<TestCase> >(*it);
+        }
+        break;
+      }
+    }
+    if (typed_test_info == NULL) {
+      typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name);
+      test_case_infos_.push_back(typed_test_info);
+    }
+    return typed_test_info;
+  }
+  void RegisterTests() {
+    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
+         it != test_case_infos_.end(); ++it) {
+      (*it)->RegisterTests();
+    }
+  }
+
+ private:
+  typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer;
+
+  TestCaseInfoContainer test_case_infos_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry);
+};
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  //  GTEST_HAS_PARAM_TEST
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
diff --git a/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-port.h b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-port.h
new file mode 100644
index 0000000..9683271
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-port.h
@@ -0,0 +1,1501 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: wan@google.com (Zhanyong Wan)
+//
+// Low-level types and utilities for porting Google Test to various
+// platforms.  They are subject to change without notice.  DO NOT USE
+// THEM IN USER CODE.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
+
+// The user can define the following macros in the build script to
+// control Google Test's behavior.  If the user doesn't define a macro
+// in this list, Google Test will define it.
+//
+//   GTEST_HAS_CLONE          - Define it to 1/0 to indicate that clone(2)
+//                              is/isn't available.
+//   GTEST_HAS_EXCEPTIONS     - Define it to 1/0 to indicate that exceptions
+//                              are enabled.
+//   GTEST_HAS_GLOBAL_STRING  - Define it to 1/0 to indicate that ::string
+//                              is/isn't available (some systems define
+//                              ::string, which is different to std::string).
+//   GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string
+//                              is/isn't available (some systems define
+//                              ::wstring, which is different to std::wstring).
+//   GTEST_HAS_PTHREAD        - Define it to 1/0 to indicate that <pthread.h>
+//                              is/isn't available.
+//   GTEST_HAS_RTTI           - Define it to 1/0 to indicate that RTTI is/isn't
+//                              enabled.
+//   GTEST_HAS_STD_WSTRING    - Define it to 1/0 to indicate that
+//                              std::wstring does/doesn't work (Google Test can
+//                              be used where std::wstring is unavailable).
+//   GTEST_HAS_TR1_TUPLE      - Define it to 1/0 to indicate tr1::tuple
+//                              is/isn't available.
+//   GTEST_HAS_SEH            - Define it to 1/0 to indicate whether the
+//                              compiler supports Microsoft's "Structured
+//                              Exception Handling".
+//   GTEST_USE_OWN_TR1_TUPLE  - Define it to 1/0 to indicate whether Google
+//                              Test's own tr1 tuple implementation should be
+//                              used.  Unused when the user sets
+//                              GTEST_HAS_TR1_TUPLE to 0.
+//   GTEST_LINKED_AS_SHARED_LIBRARY
+//                            - Define to 1 when compiling tests that use
+//                              Google Test as a shared library (known as
+//                              DLL on Windows).
+//   GTEST_CREATE_SHARED_LIBRARY
+//                            - Define to 1 when compiling Google Test itself
+//                              as a shared library.
+
+// This header defines the following utilities:
+//
+// Macros indicating the current platform (defined to 1 if compiled on
+// the given platform; otherwise undefined):
+//   GTEST_OS_AIX      - IBM AIX
+//   GTEST_OS_CYGWIN   - Cygwin
+//   GTEST_OS_HAIKU    - Haiku
+//   GTEST_OS_LINUX    - Linux
+//   GTEST_OS_MAC      - Mac OS X
+//   GTEST_OS_SOLARIS  - Sun Solaris
+//   GTEST_OS_SYMBIAN  - Symbian
+//   GTEST_OS_WINDOWS  - Windows (Desktop, MinGW, or Mobile)
+//     GTEST_OS_WINDOWS_DESKTOP  - Windows Desktop
+//     GTEST_OS_WINDOWS_MINGW    - MinGW
+//     GTEST_OS_WINDOWS_MOBILE   - Windows Mobile
+//   GTEST_OS_ZOS      - z/OS
+//
+// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the
+// most stable support.  Since core members of the Google Test project
+// don't have access to other platforms, support for them may be less
+// stable.  If you notice any problems on your platform, please notify
+// googletestframework@googlegroups.com (patches for fixing them are
+// even more welcome!).
+//
+// Note that it is possible that none of the GTEST_OS_* macros are defined.
+//
+// Macros indicating available Google Test features (defined to 1 if
+// the corresponding feature is supported; otherwise undefined):
+//   GTEST_HAS_COMBINE      - the Combine() function (for value-parameterized
+//                            tests)
+//   GTEST_HAS_DEATH_TEST   - death tests
+//   GTEST_HAS_PARAM_TEST   - value-parameterized tests
+//   GTEST_HAS_TYPED_TEST   - typed tests
+//   GTEST_HAS_TYPED_TEST_P - type-parameterized tests
+//   GTEST_USES_POSIX_RE    - enhanced POSIX regex is used.
+//   GTEST_USES_SIMPLE_RE   - our own simple regex is used;
+//                            the above two are mutually exclusive.
+//   GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ().
+//
+// Macros for basic C++ coding:
+//   GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.
+//   GTEST_ATTRIBUTE_UNUSED_  - declares that a class' instances or a
+//                              variable don't have to be used.
+//   GTEST_DISALLOW_ASSIGN_   - disables operator=.
+//   GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=.
+//   GTEST_MUST_USE_RESULT_   - declares that a function's result must be used.
+//
+// Synchronization:
+//   Mutex, MutexLock, ThreadLocal, GetThreadCount()
+//                  - synchronization primitives.
+//   GTEST_IS_THREADSAFE - defined to 1 to indicate that the above
+//                         synchronization primitives have real implementations
+//                         and Google Test is thread-safe; or 0 otherwise.
+//
+// Template meta programming:
+//   is_pointer     - as in TR1; needed on Symbian and IBM XL C/C++ only.
+//
+// Smart pointers:
+//   scoped_ptr     - as in TR2.
+//
+// Regular expressions:
+//   RE             - a simple regular expression class using the POSIX
+//                    Extended Regular Expression syntax.  Not available on
+//                    Windows.
+//
+// Logging:
+//   GTEST_LOG_()   - logs messages at the specified severity level.
+//   LogToStderr()  - directs all log messages to stderr.
+//   FlushInfoLog() - flushes informational log messages.
+//
+// Stdout and stderr capturing:
+//   CaptureStdout()     - starts capturing stdout.
+//   GetCapturedStdout() - stops capturing stdout and returns the captured
+//                         string.
+//   CaptureStderr()     - starts capturing stderr.
+//   GetCapturedStderr() - stops capturing stderr and returns the captured
+//                         string.
+//
+// Integer types:
+//   TypeWithSize   - maps an integer to a int type.
+//   Int32, UInt32, Int64, UInt64, TimeInMillis
+//                  - integers of known sizes.
+//   BiggestInt     - the biggest signed integer type.
+//
+// Command-line utilities:
+//   GTEST_FLAG()       - references a flag.
+//   GTEST_DECLARE_*()  - declares a flag.
+//   GTEST_DEFINE_*()   - defines a flag.
+//   GetArgvs()         - returns the command line as a vector of strings.
+//
+// Environment variable utilities:
+//   GetEnv()             - gets the value of an environment variable.
+//   BoolFromGTestEnv()   - parses a bool environment variable.
+//   Int32FromGTestEnv()  - parses an Int32 environment variable.
+//   StringFromGTestEnv() - parses a string environment variable.
+
+#include <stddef.h>  // For ptrdiff_t
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#ifndef _WIN32_WCE
+#include <sys/stat.h>
+#endif  // !_WIN32_WCE
+
+#include <iostream>  // NOLINT
+#include <sstream>  // NOLINT
+#include <string>  // NOLINT
+
+#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com"
+#define GTEST_FLAG_PREFIX_ "gtest_"
+#define GTEST_FLAG_PREFIX_DASH_ "gtest-"
+#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_"
+#define GTEST_NAME_ "Google Test"
+#define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/"
+
+// Determines the version of gcc that is used to compile this.
+#ifdef __GNUC__
+// 40302 means version 4.3.2.
+#define GTEST_GCC_VER_ \
+    (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__)
+#endif  // __GNUC__
+
+// Determines the platform on which Google Test is compiled.
+#ifdef __CYGWIN__
+#define GTEST_OS_CYGWIN 1
+#elif defined __SYMBIAN32__
+#define GTEST_OS_SYMBIAN 1
+#elif defined _WIN32
+#define GTEST_OS_WINDOWS 1
+#ifdef _WIN32_WCE
+#define GTEST_OS_WINDOWS_MOBILE 1
+#elif defined(__MINGW__) || defined(__MINGW32__)
+#define GTEST_OS_WINDOWS_MINGW 1
+#else
+#define GTEST_OS_WINDOWS_DESKTOP 1
+#endif  // _WIN32_WCE
+#elif defined __APPLE__
+#define GTEST_OS_MAC 1
+#elif defined __linux__
+#define GTEST_OS_LINUX 1
+#elif defined __MVS__
+#define GTEST_OS_ZOS 1
+#elif defined(__sun) && defined(__SVR4)
+#define GTEST_OS_SOLARIS 1
+#elif defined(_AIX)
+#define GTEST_OS_AIX 1
+#elif defined(__HAIKU__)
+#define GTEST_OS_HAIKU 1
+#endif  // __CYGWIN__
+
+#if GTEST_OS_CYGWIN || GTEST_OS_HAIKU || GTEST_OS_LINUX || GTEST_OS_MAC || \
+    GTEST_OS_SYMBIAN || GTEST_OS_SOLARIS || GTEST_OS_AIX
+
+// On some platforms, <regex.h> needs someone to define size_t, and
+// won't compile otherwise.  We can #include it here as we already
+// included <stdlib.h>, which is guaranteed to define size_t through
+// <stddef.h>.
+#include <regex.h>  // NOLINT
+#include <strings.h>  // NOLINT
+#include <sys/types.h>  // NOLINT
+#include <time.h>  // NOLINT
+#include <unistd.h>  // NOLINT
+
+#define GTEST_USES_POSIX_RE 1
+
+#elif GTEST_OS_WINDOWS
+
+#if !GTEST_OS_WINDOWS_MOBILE
+#include <direct.h>  // NOLINT
+#include <io.h>  // NOLINT
+#endif
+
+// <regex.h> is not available on Windows.  Use our own simple regex
+// implementation instead.
+#define GTEST_USES_SIMPLE_RE 1
+
+#else
+
+// <regex.h> may not be available on this platform.  Use our own
+// simple regex implementation instead.
+#define GTEST_USES_SIMPLE_RE 1
+
+#endif  // GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC ||
+        // GTEST_OS_SYMBIAN || GTEST_OS_SOLARIS || GTEST_OS_AIX
+
+#ifndef GTEST_HAS_EXCEPTIONS
+// The user didn't tell us whether exceptions are enabled, so we need
+// to figure it out.
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS
+// macro to enable exceptions, so we'll do the same.
+// Assumes that exceptions are enabled by default.
+#ifndef _HAS_EXCEPTIONS
+#define _HAS_EXCEPTIONS 1
+#endif  // _HAS_EXCEPTIONS
+#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS
+#elif defined(__GNUC__) && __EXCEPTIONS
+// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled.
+#define GTEST_HAS_EXCEPTIONS 1
+#elif defined(__SUNPRO_CC)
+// Sun Pro CC supports exceptions.  However, there is no compile-time way of
+// detecting whether they are enabled or not.  Therefore, we assume that
+// they are enabled unless the user tells us otherwise.
+#define GTEST_HAS_EXCEPTIONS 1
+#elif defined(__IBMCPP__) && __EXCEPTIONS
+// xlC defines __EXCEPTIONS to 1 iff exceptions are enabled.
+#define GTEST_HAS_EXCEPTIONS 1
+#else
+// For other compilers, we assume exceptions are disabled to be
+// conservative.
+#define GTEST_HAS_EXCEPTIONS 0
+#endif  // defined(_MSC_VER) || defined(__BORLANDC__)
+#endif  // GTEST_HAS_EXCEPTIONS
+
+#if !defined(GTEST_HAS_STD_STRING)
+// Even though we don't use this macro any longer, we keep it in case
+// some clients still depend on it.
+#define GTEST_HAS_STD_STRING 1
+#elif !GTEST_HAS_STD_STRING
+// The user told us that ::std::string isn't available.
+#error "Google Test cannot be used where ::std::string isn't available."
+#endif  // !defined(GTEST_HAS_STD_STRING)
+
+#ifndef GTEST_HAS_GLOBAL_STRING
+// The user didn't tell us whether ::string is available, so we need
+// to figure it out.
+
+#define GTEST_HAS_GLOBAL_STRING 0
+
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+#ifndef GTEST_HAS_STD_WSTRING
+// The user didn't tell us whether ::std::wstring is available, so we need
+// to figure it out.
+// TODO(wan@google.com): uses autoconf to detect whether ::std::wstring
+//   is available.
+
+// Cygwin 1.5 and below doesn't support ::std::wstring.
+// Cygwin 1.7 might add wstring support; this should be updated when clear.
+// Solaris' libc++ doesn't support it either.
+// Minix currently doesn't support it either.
+#define GTEST_HAS_STD_WSTRING (!(GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || GTEST_OS_HAIKU || defined(_MINIX)))
+
+#endif  // GTEST_HAS_STD_WSTRING
+
+#ifndef GTEST_HAS_GLOBAL_WSTRING
+// The user didn't tell us whether ::wstring is available, so we need
+// to figure it out.
+#define GTEST_HAS_GLOBAL_WSTRING \
+    (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING)
+#endif  // GTEST_HAS_GLOBAL_WSTRING
+
+// Determines whether RTTI is available.
+#ifndef GTEST_HAS_RTTI
+// The user didn't tell us whether RTTI is enabled, so we need to
+// figure it out.
+
+#ifdef _MSC_VER
+
+#ifdef _CPPRTTI  // MSVC defines this macro iff RTTI is enabled.
+#define GTEST_HAS_RTTI 1
+#else
+#define GTEST_HAS_RTTI 0
+#endif
+
+// Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled.
+#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302)
+
+#ifdef __GXX_RTTI
+#define GTEST_HAS_RTTI 1
+#else
+#define GTEST_HAS_RTTI 0
+#endif  // __GXX_RTTI
+
+// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if
+// both the typeid and dynamic_cast features are present.
+#elif defined(__IBMCPP__) && (__IBMCPP__ >= 900)
+
+#ifdef __RTTI_ALL__
+#define GTEST_HAS_RTTI 1
+#else
+#define GTEST_HAS_RTTI 0
+#endif
+
+#else
+
+// For all other compilers, we assume RTTI is enabled.
+#define GTEST_HAS_RTTI 1
+
+#endif  // _MSC_VER
+
+#endif  // GTEST_HAS_RTTI
+
+// It's this header's responsibility to #include <typeinfo> when RTTI
+// is enabled.
+#if GTEST_HAS_RTTI
+#include <typeinfo>
+#endif
+
+// Determines whether Google Test can use the pthreads library.
+#ifndef GTEST_HAS_PTHREAD
+// The user didn't tell us explicitly, so we assume pthreads support is
+// available on Linux and Mac.
+//
+// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0
+// to your compiler flags.
+#define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC)
+#endif  // GTEST_HAS_PTHREAD
+
+// Determines whether Google Test can use tr1/tuple.  You can define
+// this macro to 0 to prevent Google Test from using tuple (any
+// feature depending on tuple with be disabled in this mode).
+#ifndef GTEST_HAS_TR1_TUPLE
+// The user didn't tell us not to do it, so we assume it's OK.
+#define GTEST_HAS_TR1_TUPLE 1
+#endif  // GTEST_HAS_TR1_TUPLE
+
+// Determines whether Google Test's own tr1 tuple implementation
+// should be used.
+#ifndef GTEST_USE_OWN_TR1_TUPLE
+// The user didn't tell us, so we need to figure it out.
+
+// We use our own TR1 tuple if we aren't sure the user has an
+// implementation of it already.  At this time, GCC 4.0.0+ and MSVC
+// 2010 are the only mainstream compilers that come with a TR1 tuple
+// implementation.  NVIDIA's CUDA NVCC compiler pretends to be GCC by
+// defining __GNUC__ and friends, but cannot compile GCC's tuple
+// implementation.  MSVC 2008 (9.0) provides TR1 tuple in a 323 MB
+// Feature Pack download, which we cannot assume the user has.
+#if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000)) \
+    || _MSC_VER >= 1600
+#define GTEST_USE_OWN_TR1_TUPLE 0
+#else
+#define GTEST_USE_OWN_TR1_TUPLE 1
+#endif
+
+#endif  // GTEST_USE_OWN_TR1_TUPLE
+
+// To avoid conditional compilation everywhere, we make it
+// gtest-port.h's responsibility to #include the header implementing
+// tr1/tuple.
+#if GTEST_HAS_TR1_TUPLE
+
+#if GTEST_USE_OWN_TR1_TUPLE
+#include <gtest/internal/gtest-tuple.h>
+#elif GTEST_OS_SYMBIAN
+
+// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to
+// use STLport's tuple implementation, which unfortunately doesn't
+// work as the copy of STLport distributed with Symbian is incomplete.
+// By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to
+// use its own tuple implementation.
+#ifdef BOOST_HAS_TR1_TUPLE
+#undef BOOST_HAS_TR1_TUPLE
+#endif  // BOOST_HAS_TR1_TUPLE
+
+// This prevents <boost/tr1/detail/config.hpp>, which defines
+// BOOST_HAS_TR1_TUPLE, from being #included by Boost's <tuple>.
+#define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED
+#include <tuple>
+
+#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)
+// GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header.  This does
+// not conform to the TR1 spec, which requires the header to be <tuple>.
+
+#if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302
+// Until version 4.3.2, gcc has a bug that causes <tr1/functional>,
+// which is #included by <tr1/tuple>, to not compile when RTTI is
+// disabled.  _TR1_FUNCTIONAL is the header guard for
+// <tr1/functional>.  Hence the following #define is a hack to prevent
+// <tr1/functional> from being included.
+#define _TR1_FUNCTIONAL 1
+#include <tr1/tuple>
+#undef _TR1_FUNCTIONAL  // Allows the user to #include
+                        // <tr1/functional> if he chooses to.
+#else
+#include <tr1/tuple>  // NOLINT
+#endif  // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302
+
+#else
+// If the compiler is not GCC 4.0+, we assume the user is using a
+// spec-conforming TR1 implementation.
+#include <tuple>  // NOLINT
+#endif  // GTEST_USE_OWN_TR1_TUPLE
+
+#endif  // GTEST_HAS_TR1_TUPLE
+
+// Determines whether clone(2) is supported.
+// Usually it will only be available on Linux, excluding
+// Linux on the Itanium architecture.
+// Also see http://linux.die.net/man/2/clone.
+#ifndef GTEST_HAS_CLONE
+// The user didn't tell us, so we need to figure it out.
+
+#if GTEST_OS_LINUX && !defined(__ia64__)
+#define GTEST_HAS_CLONE 1
+#else
+#define GTEST_HAS_CLONE 0
+#endif  // GTEST_OS_LINUX && !defined(__ia64__)
+
+#endif  // GTEST_HAS_CLONE
+
+// Determines whether to support stream redirection. This is used to test
+// output correctness and to implement death tests.
+#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN
+#define GTEST_HAS_STREAM_REDIRECTION_ 1
+#endif  // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN
+
+// Determines whether to support death tests.
+// Google Test does not support death tests for VC 7.1 and earlier as
+// abort() in a VC 7.1 application compiled as GUI in debug config
+// pops up a dialog window that cannot be suppressed programmatically.
+#if (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
+     (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \
+     GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX)
+#define GTEST_HAS_DEATH_TEST 1
+#include <vector>  // NOLINT
+#endif
+
+// We don't support MSVC 7.1 with exceptions disabled now.  Therefore
+// all the compilers we care about are adequate for supporting
+// value-parameterized tests.
+#define GTEST_HAS_PARAM_TEST 1
+
+// Determines whether to support type-driven tests.
+
+// Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0,
+// Sun Pro CC, and IBM Visual Age support.
+#if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \
+    defined(__IBMCPP__)
+#define GTEST_HAS_TYPED_TEST 1
+#define GTEST_HAS_TYPED_TEST_P 1
+#endif
+
+// Determines whether to support Combine(). This only makes sense when
+// value-parameterized tests are enabled.  The implementation doesn't
+// work on Sun Studio since it doesn't understand templated conversion
+// operators.
+#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC)
+#define GTEST_HAS_COMBINE 1
+#endif
+
+// Determines whether the system compiler uses UTF-16 for encoding wide strings.
+#define GTEST_WIDE_STRING_USES_UTF16_ \
+    (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX)
+
+// Defines some utility macros.
+
+// The GNU compiler emits a warning if nested "if" statements are followed by
+// an "else" statement and braces are not used to explicitly disambiguate the
+// "else" binding.  This leads to problems with code like:
+//
+//   if (gate)
+//     ASSERT_*(condition) << "Some message";
+//
+// The "switch (0) case 0:" idiom is used to suppress this.
+#ifdef __INTEL_COMPILER
+#define GTEST_AMBIGUOUS_ELSE_BLOCKER_
+#else
+#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0:  // NOLINT
+#endif
+
+// Use this annotation at the end of a struct/class definition to
+// prevent the compiler from optimizing away instances that are never
+// used.  This is useful when all interesting logic happens inside the
+// c'tor and / or d'tor.  Example:
+//
+//   struct Foo {
+//     Foo() { ... }
+//   } GTEST_ATTRIBUTE_UNUSED_;
+//
+// Also use it after a variable or parameter declaration to tell the
+// compiler the variable/parameter does not have to be used.
+#if defined(__GNUC__) && !defined(COMPILER_ICC)
+#define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused))
+#else
+#define GTEST_ATTRIBUTE_UNUSED_
+#endif
+
+// A macro to disallow operator=
+// This should be used in the private: declarations for a class.
+#define GTEST_DISALLOW_ASSIGN_(type)\
+  void operator=(type const &)
+
+// A macro to disallow copy constructor and operator=
+// This should be used in the private: declarations for a class.
+#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\
+  type(type const &);\
+  GTEST_DISALLOW_ASSIGN_(type)
+
+// Tell the compiler to warn about unused return values for functions declared
+// with this macro.  The macro should be used on function declarations
+// following the argument list:
+//
+//   Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_;
+#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC)
+#define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result))
+#else
+#define GTEST_MUST_USE_RESULT_
+#endif  // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC
+
+// Determine whether the compiler supports Microsoft's Structured Exception
+// Handling.  This is supported by several Windows compilers but generally
+// does not exist on any other system.
+#ifndef GTEST_HAS_SEH
+// The user didn't tell us, so we need to figure it out.
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+// These two compilers are known to support SEH.
+#define GTEST_HAS_SEH 1
+#else
+// Assume no SEH.
+#define GTEST_HAS_SEH 0
+#endif
+
+#endif  // GTEST_HAS_SEH
+
+#ifdef _MSC_VER
+
+#if GTEST_LINKED_AS_SHARED_LIBRARY
+#define GTEST_API_ __declspec(dllimport)
+#elif GTEST_CREATE_SHARED_LIBRARY
+#define GTEST_API_ __declspec(dllexport)
+#endif
+
+#endif  // _MSC_VER
+
+#ifndef GTEST_API_
+#define GTEST_API_
+#endif
+
+namespace testing {
+
+class Message;
+
+namespace internal {
+
+class String;
+
+typedef ::std::stringstream StrStream;
+
+// A helper for suppressing warnings on constant condition.  It just
+// returns 'condition'.
+GTEST_API_ bool IsTrue(bool condition);
+
+// Defines scoped_ptr.
+
+// This implementation of scoped_ptr is PARTIAL - it only contains
+// enough stuff to satisfy Google Test's need.
+template <typename T>
+class scoped_ptr {
+ public:
+  typedef T element_type;
+
+  explicit scoped_ptr(T* p = NULL) : ptr_(p) {}
+  ~scoped_ptr() { reset(); }
+
+  T& operator*() const { return *ptr_; }
+  T* operator->() const { return ptr_; }
+  T* get() const { return ptr_; }
+
+  T* release() {
+    T* const ptr = ptr_;
+    ptr_ = NULL;
+    return ptr;
+  }
+
+  void reset(T* p = NULL) {
+    if (p != ptr_) {
+      if (IsTrue(sizeof(T) > 0)) {  // Makes sure T is a complete type.
+        delete ptr_;
+      }
+      ptr_ = p;
+    }
+  }
+ private:
+  T* ptr_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr);
+};
+
+// Defines RE.
+
+// A simple C++ wrapper for <regex.h>.  It uses the POSIX Extended
+// Regular Expression syntax.
+class GTEST_API_ RE {
+ public:
+  // A copy constructor is required by the Standard to initialize object
+  // references from r-values.
+  RE(const RE& other) { Init(other.pattern()); }
+
+  // Constructs an RE from a string.
+  RE(const ::std::string& regex) { Init(regex.c_str()); }  // NOLINT
+
+#if GTEST_HAS_GLOBAL_STRING
+  RE(const ::string& regex) { Init(regex.c_str()); }  // NOLINT
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+  RE(const char* regex) { Init(regex); }  // NOLINT
+  ~RE();
+
+  // Returns the string representation of the regex.
+  const char* pattern() const { return pattern_; }
+
+  // FullMatch(str, re) returns true iff regular expression re matches
+  // the entire str.
+  // PartialMatch(str, re) returns true iff regular expression re
+  // matches a substring of str (including str itself).
+  //
+  // TODO(wan@google.com): make FullMatch() and PartialMatch() work
+  // when str contains NUL characters.
+  static bool FullMatch(const ::std::string& str, const RE& re) {
+    return FullMatch(str.c_str(), re);
+  }
+  static bool PartialMatch(const ::std::string& str, const RE& re) {
+    return PartialMatch(str.c_str(), re);
+  }
+
+#if GTEST_HAS_GLOBAL_STRING
+  static bool FullMatch(const ::string& str, const RE& re) {
+    return FullMatch(str.c_str(), re);
+  }
+  static bool PartialMatch(const ::string& str, const RE& re) {
+    return PartialMatch(str.c_str(), re);
+  }
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+  static bool FullMatch(const char* str, const RE& re);
+  static bool PartialMatch(const char* str, const RE& re);
+
+ private:
+  void Init(const char* regex);
+
+  // We use a const char* instead of a string, as Google Test may be used
+  // where string is not available.  We also do not use Google Test's own
+  // String type here, in order to simplify dependencies between the
+  // files.
+  const char* pattern_;
+  bool is_valid_;
+#if GTEST_USES_POSIX_RE
+  regex_t full_regex_;     // For FullMatch().
+  regex_t partial_regex_;  // For PartialMatch().
+#else  // GTEST_USES_SIMPLE_RE
+  const char* full_pattern_;  // For FullMatch();
+#endif
+
+  GTEST_DISALLOW_ASSIGN_(RE);
+};
+
+// Defines logging utilities:
+//   GTEST_LOG_(severity) - logs messages at the specified severity level. The
+//                          message itself is streamed into the macro.
+//   LogToStderr()  - directs all log messages to stderr.
+//   FlushInfoLog() - flushes informational log messages.
+
+enum GTestLogSeverity {
+  GTEST_INFO,
+  GTEST_WARNING,
+  GTEST_ERROR,
+  GTEST_FATAL
+};
+
+// Formats log entry severity, provides a stream object for streaming the
+// log message, and terminates the message with a newline when going out of
+// scope.
+class GTEST_API_ GTestLog {
+ public:
+  GTestLog(GTestLogSeverity severity, const char* file, int line);
+
+  // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
+  ~GTestLog();
+
+  ::std::ostream& GetStream() { return ::std::cerr; }
+
+ private:
+  const GTestLogSeverity severity_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog);
+};
+
+#define GTEST_LOG_(severity) \
+    ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \
+                                  __FILE__, __LINE__).GetStream()
+
+inline void LogToStderr() {}
+inline void FlushInfoLog() { fflush(NULL); }
+
+// INTERNAL IMPLEMENTATION - DO NOT USE.
+//
+// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition
+// is not satisfied.
+//  Synopsys:
+//    GTEST_CHECK_(boolean_condition);
+//     or
+//    GTEST_CHECK_(boolean_condition) << "Additional message";
+//
+//    This checks the condition and if the condition is not satisfied
+//    it prints message about the condition violation, including the
+//    condition itself, plus additional message streamed into it, if any,
+//    and then it aborts the program. It aborts the program irrespective of
+//    whether it is built in the debug mode or not.
+#define GTEST_CHECK_(condition) \
+    GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+    if (::testing::internal::IsTrue(condition)) \
+      ; \
+    else \
+      GTEST_LOG_(FATAL) << "Condition " #condition " failed. "
+
+// An all-mode assert to verify that the given POSIX-style function
+// call returns 0 (indicating success).  Known limitation: this
+// doesn't expand to a balanced 'if' statement, so enclose the macro
+// in {} if you need to use it as the only statement in an 'if'
+// branch.
+#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \
+  if (const int gtest_error = (posix_call)) \
+    GTEST_LOG_(FATAL) << #posix_call << "failed with error " \
+                      << gtest_error
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Downcasts the pointer of type Base to Derived.
+// Derived must be a subclass of Base. The parameter MUST
+// point to a class of type Derived, not any subclass of it.
+// When RTTI is available, the function performs a runtime
+// check to enforce this.
+template <class Derived, class Base>
+Derived* CheckedDowncastToActualType(Base* base) {
+#if GTEST_HAS_RTTI
+  GTEST_CHECK_(typeid(*base) == typeid(Derived));
+  return dynamic_cast<Derived*>(base);  // NOLINT
+#else
+  return static_cast<Derived*>(base);  // Poor man's downcast.
+#endif
+}
+
+#if GTEST_HAS_STREAM_REDIRECTION_
+
+// Defines the stderr capturer:
+//   CaptureStdout     - starts capturing stdout.
+//   GetCapturedStdout - stops capturing stdout and returns the captured string.
+//   CaptureStderr     - starts capturing stderr.
+//   GetCapturedStderr - stops capturing stderr and returns the captured string.
+//
+GTEST_API_ void CaptureStdout();
+GTEST_API_ String GetCapturedStdout();
+GTEST_API_ void CaptureStderr();
+GTEST_API_ String GetCapturedStderr();
+
+#endif  // GTEST_HAS_STREAM_REDIRECTION_
+
+
+#if GTEST_HAS_DEATH_TEST
+
+// A copy of all command line arguments.  Set by InitGoogleTest().
+extern ::std::vector<String> g_argvs;
+
+// GTEST_HAS_DEATH_TEST implies we have ::std::string.
+const ::std::vector<String>& GetArgvs();
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+// Defines synchronization primitives.
+
+#if GTEST_HAS_PTHREAD
+
+// Sleeps for (roughly) n milli-seconds.  This function is only for
+// testing Google Test's own constructs.  Don't use it in user tests,
+// either directly or indirectly.
+inline void SleepMilliseconds(int n) {
+  const timespec time = {
+    0,                  // 0 seconds.
+    n * 1000L * 1000L,  // And n ms.
+  };
+  nanosleep(&time, NULL);
+}
+
+// Allows a controller thread to pause execution of newly created
+// threads until notified.  Instances of this class must be created
+// and destroyed in the controller thread.
+//
+// This class is only for testing Google Test's own constructs. Do not
+// use it in user tests, either directly or indirectly.
+class Notification {
+ public:
+  Notification() : notified_(false) {}
+
+  // Notifies all threads created with this notification to start. Must
+  // be called from the controller thread.
+  void Notify() { notified_ = true; }
+
+  // Blocks until the controller thread notifies. Must be called from a test
+  // thread.
+  void WaitForNotification() {
+    while(!notified_) {
+      SleepMilliseconds(10);
+    }
+  }
+
+ private:
+  volatile bool notified_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);
+};
+
+// As a C-function, ThreadFuncWithCLinkage cannot be templated itself.
+// Consequently, it cannot select a correct instantiation of ThreadWithParam
+// in order to call its Run(). Introducing ThreadWithParamBase as a
+// non-templated base class for ThreadWithParam allows us to bypass this
+// problem.
+class ThreadWithParamBase {
+ public:
+  virtual ~ThreadWithParamBase() {}
+  virtual void Run() = 0;
+};
+
+// pthread_create() accepts a pointer to a function type with the C linkage.
+// According to the Standard (7.5/1), function types with different linkages
+// are different even if they are otherwise identical.  Some compilers (for
+// example, SunStudio) treat them as different types.  Since class methods
+// cannot be defined with C-linkage we need to define a free C-function to
+// pass into pthread_create().
+extern "C" inline void* ThreadFuncWithCLinkage(void* thread) {
+  static_cast<ThreadWithParamBase*>(thread)->Run();
+  return NULL;
+}
+
+// Helper class for testing Google Test's multi-threading constructs.
+// To use it, write:
+//
+//   void ThreadFunc(int param) { /* Do things with param */ }
+//   Notification thread_can_start;
+//   ...
+//   // The thread_can_start parameter is optional; you can supply NULL.
+//   ThreadWithParam<int> thread(&ThreadFunc, 5, &thread_can_start);
+//   thread_can_start.Notify();
+//
+// These classes are only for testing Google Test's own constructs. Do
+// not use them in user tests, either directly or indirectly.
+template <typename T>
+class ThreadWithParam : public ThreadWithParamBase {
+ public:
+  typedef void (*UserThreadFunc)(T);
+
+  ThreadWithParam(
+      UserThreadFunc func, T param, Notification* thread_can_start)
+      : func_(func),
+        param_(param),
+        thread_can_start_(thread_can_start),
+        finished_(false) {
+    ThreadWithParamBase* const base = this;
+    // The thread can be created only after all fields except thread_
+    // have been initialized.
+    GTEST_CHECK_POSIX_SUCCESS_(
+        pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base));
+  }
+  ~ThreadWithParam() { Join(); }
+
+  void Join() {
+    if (!finished_) {
+      GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0));
+      finished_ = true;
+    }
+  }
+
+  virtual void Run() {
+    if (thread_can_start_ != NULL)
+      thread_can_start_->WaitForNotification();
+    func_(param_);
+  }
+
+ private:
+  const UserThreadFunc func_;  // User-supplied thread function.
+  const T param_;  // User-supplied parameter to the thread function.
+  // When non-NULL, used to block execution until the controller thread
+  // notifies.
+  Notification* const thread_can_start_;
+  bool finished_;  // true iff we know that the thread function has finished.
+  pthread_t thread_;  // The native thread object.
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam);
+};
+
+// gtest-port.h guarantees to #include <pthread.h> when GTEST_HAS_PTHREAD is
+// true.
+#include <pthread.h>
+
+// MutexBase and Mutex implement mutex on pthreads-based platforms. They
+// are used in conjunction with class MutexLock:
+//
+//   Mutex mutex;
+//   ...
+//   MutexLock lock(&mutex);  // Acquires the mutex and releases it at the end
+//                            // of the current scope.
+//
+// MutexBase implements behavior for both statically and dynamically
+// allocated mutexes.  Do not use MutexBase directly.  Instead, write
+// the following to define a static mutex:
+//
+//   GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex);
+//
+// You can forward declare a static mutex like this:
+//
+//   GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex);
+//
+// To create a dynamic mutex, just define an object of type Mutex.
+class MutexBase {
+ public:
+  // Acquires this mutex.
+  void Lock() {
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));
+    owner_ = pthread_self();
+  }
+
+  // Releases this mutex.
+  void Unlock() {
+    // We don't protect writing to owner_ here, as it's the caller's
+    // responsibility to ensure that the current thread holds the
+    // mutex when this is called.
+    owner_ = 0;
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_));
+  }
+
+  // Does nothing if the current thread holds the mutex. Otherwise, crashes
+  // with high probability.
+  void AssertHeld() const {
+    GTEST_CHECK_(owner_ == pthread_self())
+        << "The current thread is not holding the mutex @" << this;
+  }
+
+  // A static mutex may be used before main() is entered.  It may even
+  // be used before the dynamic initialization stage.  Therefore we
+  // must be able to initialize a static mutex object at link time.
+  // This means MutexBase has to be a POD and its member variables
+  // have to be public.
+ public:
+  pthread_mutex_t mutex_;  // The underlying pthread mutex.
+  pthread_t owner_;  // The thread holding the mutex; 0 means no one holds it.
+};
+
+// Forward-declares a static mutex.
+#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
+    extern ::testing::internal::MutexBase mutex
+
+// Defines and statically (i.e. at link time) initializes a static mutex.
+#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
+    ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, 0 }
+
+// The Mutex class can only be used for mutexes created at runtime. It
+// shares its API with MutexBase otherwise.
+class Mutex : public MutexBase {
+ public:
+  Mutex() {
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL));
+    owner_ = 0;
+  }
+  ~Mutex() {
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_));
+  }
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex);
+};
+
+// We cannot name this class MutexLock as the ctor declaration would
+// conflict with a macro named MutexLock, which is defined on some
+// platforms.  Hence the typedef trick below.
+class GTestMutexLock {
+ public:
+  explicit GTestMutexLock(MutexBase* mutex)
+      : mutex_(mutex) { mutex_->Lock(); }
+
+  ~GTestMutexLock() { mutex_->Unlock(); }
+
+ private:
+  MutexBase* const mutex_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock);
+};
+
+typedef GTestMutexLock MutexLock;
+
+// Helpers for ThreadLocal.
+
+// pthread_key_create() requires DeleteThreadLocalValue() to have
+// C-linkage.  Therefore it cannot be templatized to access
+// ThreadLocal<T>.  Hence the need for class
+// ThreadLocalValueHolderBase.
+class ThreadLocalValueHolderBase {
+ public:
+  virtual ~ThreadLocalValueHolderBase() {}
+};
+
+// Called by pthread to delete thread-local data stored by
+// pthread_setspecific().
+extern "C" inline void DeleteThreadLocalValue(void* value_holder) {
+  delete static_cast<ThreadLocalValueHolderBase*>(value_holder);
+}
+
+// Implements thread-local storage on pthreads-based systems.
+//
+//   // Thread 1
+//   ThreadLocal<int> tl(100);  // 100 is the default value for each thread.
+//
+//   // Thread 2
+//   tl.set(150);  // Changes the value for thread 2 only.
+//   EXPECT_EQ(150, tl.get());
+//
+//   // Thread 1
+//   EXPECT_EQ(100, tl.get());  // In thread 1, tl has the original value.
+//   tl.set(200);
+//   EXPECT_EQ(200, tl.get());
+//
+// The template type argument T must have a public copy constructor.
+// In addition, the default ThreadLocal constructor requires T to have
+// a public default constructor.
+//
+// An object managed for a thread by a ThreadLocal instance is deleted
+// when the thread exits.  Or, if the ThreadLocal instance dies in
+// that thread, when the ThreadLocal dies.  It's the user's
+// responsibility to ensure that all other threads using a ThreadLocal
+// have exited when it dies, or the per-thread objects for those
+// threads will not be deleted.
+//
+// Google Test only uses global ThreadLocal objects.  That means they
+// will die after main() has returned.  Therefore, no per-thread
+// object managed by Google Test will be leaked as long as all threads
+// using Google Test have exited when main() returns.
+template <typename T>
+class ThreadLocal {
+ public:
+  ThreadLocal() : key_(CreateKey()),
+                  default_() {}
+  explicit ThreadLocal(const T& value) : key_(CreateKey()),
+                                         default_(value) {}
+
+  ~ThreadLocal() {
+    // Destroys the managed object for the current thread, if any.
+    DeleteThreadLocalValue(pthread_getspecific(key_));
+
+    // Releases resources associated with the key.  This will *not*
+    // delete managed objects for other threads.
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_));
+  }
+
+  T* pointer() { return GetOrCreateValue(); }
+  const T* pointer() const { return GetOrCreateValue(); }
+  const T& get() const { return *pointer(); }
+  void set(const T& value) { *pointer() = value; }
+
+ private:
+  // Holds a value of type T.
+  class ValueHolder : public ThreadLocalValueHolderBase {
+   public:
+    explicit ValueHolder(const T& value) : value_(value) {}
+
+    T* pointer() { return &value_; }
+
+   private:
+    T value_;
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder);
+  };
+
+  static pthread_key_t CreateKey() {
+    pthread_key_t key;
+    // When a thread exits, DeleteThreadLocalValue() will be called on
+    // the object managed for that thread.
+    GTEST_CHECK_POSIX_SUCCESS_(
+        pthread_key_create(&key, &DeleteThreadLocalValue));
+    return key;
+  }
+
+  T* GetOrCreateValue() const {
+    ThreadLocalValueHolderBase* const holder =
+        static_cast<ThreadLocalValueHolderBase*>(pthread_getspecific(key_));
+    if (holder != NULL) {
+      return CheckedDowncastToActualType<ValueHolder>(holder)->pointer();
+    }
+
+    ValueHolder* const new_holder = new ValueHolder(default_);
+    ThreadLocalValueHolderBase* const holder_base = new_holder;
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base));
+    return new_holder->pointer();
+  }
+
+  // A key pthreads uses for looking up per-thread values.
+  const pthread_key_t key_;
+  const T default_;  // The default value for each thread.
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
+};
+
+#define GTEST_IS_THREADSAFE 1
+
+#else  // GTEST_HAS_PTHREAD
+
+// A dummy implementation of synchronization primitives (mutex, lock,
+// and thread-local variable).  Necessary for compiling Google Test where
+// mutex is not supported - using Google Test in multiple threads is not
+// supported on such platforms.
+
+class Mutex {
+ public:
+  Mutex() {}
+  void AssertHeld() const {}
+};
+
+#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
+  extern ::testing::internal::Mutex mutex
+
+#define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex
+
+class GTestMutexLock {
+ public:
+  explicit GTestMutexLock(Mutex*) {}  // NOLINT
+};
+
+typedef GTestMutexLock MutexLock;
+
+template <typename T>
+class ThreadLocal {
+ public:
+  ThreadLocal() : value_() {}
+  explicit ThreadLocal(const T& value) : value_(value) {}
+  T* pointer() { return &value_; }
+  const T* pointer() const { return &value_; }
+  const T& get() const { return value_; }
+  void set(const T& value) { value_ = value; }
+ private:
+  T value_;
+};
+
+// The above synchronization primitives have dummy implementations.
+// Therefore Google Test is not thread-safe.
+#define GTEST_IS_THREADSAFE 0
+
+#endif  // GTEST_HAS_PTHREAD
+
+// Returns the number of threads running in the process, or 0 to indicate that
+// we cannot detect it.
+GTEST_API_ size_t GetThreadCount();
+
+// Passing non-POD classes through ellipsis (...) crashes the ARM
+// compiler and generates a warning in Sun Studio.  The Nokia Symbian
+// and the IBM XL C/C++ compiler try to instantiate a copy constructor
+// for objects passed through ellipsis (...), failing for uncopyable
+// objects.  We define this to ensure that only POD is passed through
+// ellipsis on these systems.
+#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC)
+// We lose support for NULL detection where the compiler doesn't like
+// passing non-POD classes through ellipsis (...).
+#define GTEST_ELLIPSIS_NEEDS_POD_ 1
+#else
+#define GTEST_CAN_COMPARE_NULL 1
+#endif
+
+// The Nokia Symbian and IBM XL C/C++ compilers cannot decide between
+// const T& and const T* in a function template.  These compilers
+// _can_ decide between class template specializations for T and T*,
+// so a tr1::type_traits-like is_pointer works.
+#if defined(__SYMBIAN32__) || defined(__IBMCPP__)
+#define GTEST_NEEDS_IS_POINTER_ 1
+#endif
+
+template <bool bool_value>
+struct bool_constant {
+  typedef bool_constant<bool_value> type;
+  static const bool value = bool_value;
+};
+template <bool bool_value> const bool bool_constant<bool_value>::value;
+
+typedef bool_constant<false> false_type;
+typedef bool_constant<true> true_type;
+
+template <typename T>
+struct is_pointer : public false_type {};
+
+template <typename T>
+struct is_pointer<T*> : public true_type {};
+
+#if GTEST_OS_WINDOWS
+#define GTEST_PATH_SEP_ "\\"
+#define GTEST_HAS_ALT_PATH_SEP_ 1
+// The biggest signed integer type the compiler supports.
+typedef __int64 BiggestInt;
+#else
+#define GTEST_PATH_SEP_ "/"
+#define GTEST_HAS_ALT_PATH_SEP_ 0
+typedef long long BiggestInt;  // NOLINT
+#endif  // GTEST_OS_WINDOWS
+
+// The testing::internal::posix namespace holds wrappers for common
+// POSIX functions.  These wrappers hide the differences between
+// Windows/MSVC and POSIX systems.  Since some compilers define these
+// standard functions as macros, the wrapper cannot have the same name
+// as the wrapped function.
+
+namespace posix {
+
+// Functions with a different name on Windows.
+
+#if GTEST_OS_WINDOWS
+
+typedef struct _stat StatStruct;
+
+#ifdef __BORLANDC__
+inline int IsATTY(int fd) { return isatty(fd); }
+inline int StrCaseCmp(const char* s1, const char* s2) {
+  return stricmp(s1, s2);
+}
+inline char* StrDup(const char* src) { return strdup(src); }
+#else  // !__BORLANDC__
+#if GTEST_OS_WINDOWS_MOBILE
+inline int IsATTY(int /* fd */) { return 0; }
+#else
+inline int IsATTY(int fd) { return _isatty(fd); }
+#endif  // GTEST_OS_WINDOWS_MOBILE
+inline int StrCaseCmp(const char* s1, const char* s2) {
+  return _stricmp(s1, s2);
+}
+inline char* StrDup(const char* src) { return _strdup(src); }
+#endif  // __BORLANDC__
+
+#if GTEST_OS_WINDOWS_MOBILE
+inline int FileNo(FILE* file) { return reinterpret_cast<int>(_fileno(file)); }
+// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this
+// time and thus not defined there.
+#else
+inline int FileNo(FILE* file) { return _fileno(file); }
+inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); }
+inline int RmDir(const char* dir) { return _rmdir(dir); }
+inline bool IsDir(const StatStruct& st) {
+  return (_S_IFDIR & st.st_mode) != 0;
+}
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+#else
+
+typedef struct stat StatStruct;
+
+inline int FileNo(FILE* file) { return fileno(file); }
+inline int IsATTY(int fd) { return isatty(fd); }
+inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); }
+inline int StrCaseCmp(const char* s1, const char* s2) {
+  return strcasecmp(s1, s2);
+}
+inline char* StrDup(const char* src) { return strdup(src); }
+inline int RmDir(const char* dir) { return rmdir(dir); }
+inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
+
+#endif  // GTEST_OS_WINDOWS
+
+// Functions deprecated by MSVC 8.0.
+
+#ifdef _MSC_VER
+// Temporarily disable warning 4996 (deprecated function).
+#pragma warning(push)
+#pragma warning(disable:4996)
+#endif
+
+inline const char* StrNCpy(char* dest, const char* src, size_t n) {
+  return strncpy(dest, src, n);
+}
+
+// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and
+// StrError() aren't needed on Windows CE at this time and thus not
+// defined there.
+
+#if !GTEST_OS_WINDOWS_MOBILE
+inline int ChDir(const char* dir) { return chdir(dir); }
+#endif
+inline FILE* FOpen(const char* path, const char* mode) {
+  return fopen(path, mode);
+}
+#if !GTEST_OS_WINDOWS_MOBILE
+inline FILE *FReopen(const char* path, const char* mode, FILE* stream) {
+  return freopen(path, mode, stream);
+}
+inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); }
+#endif
+inline int FClose(FILE* fp) { return fclose(fp); }
+#if !GTEST_OS_WINDOWS_MOBILE
+inline int Read(int fd, void* buf, unsigned int count) {
+  return static_cast<int>(read(fd, buf, count));
+}
+inline int Write(int fd, const void* buf, unsigned int count) {
+  return static_cast<int>(write(fd, buf, count));
+}
+inline int Close(int fd) { return close(fd); }
+inline const char* StrError(int errnum) { return strerror(errnum); }
+#endif
+inline const char* GetEnv(const char* name) {
+#if GTEST_OS_WINDOWS_MOBILE
+  // We are on Windows CE, which has no environment variables.
+  return NULL;
+#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
+  // Environment variables which we programmatically clear will be set to the
+  // empty string rather than unset (NULL).  Handle that case.
+  const char* const env = getenv(name);
+  return (env != NULL && env[0] != '\0') ? env : NULL;
+#else
+  return getenv(name);
+#endif
+}
+
+#ifdef _MSC_VER
+#pragma warning(pop)  // Restores the warning state.
+#endif
+
+#if GTEST_OS_WINDOWS_MOBILE
+// Windows CE has no C library. The abort() function is used in
+// several places in Google Test. This implementation provides a reasonable
+// imitation of standard behaviour.
+void Abort();
+#else
+inline void Abort() { abort(); }
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+}  // namespace posix
+
+// The maximum number a BiggestInt can represent.  This definition
+// works no matter BiggestInt is represented in one's complement or
+// two's complement.
+//
+// We cannot rely on numeric_limits in STL, as __int64 and long long
+// are not part of standard C++ and numeric_limits doesn't need to be
+// defined for them.
+const BiggestInt kMaxBiggestInt =
+    ~(static_cast<BiggestInt>(1) << (8*sizeof(BiggestInt) - 1));
+
+// This template class serves as a compile-time function from size to
+// type.  It maps a size in bytes to a primitive type with that
+// size. e.g.
+//
+//   TypeWithSize<4>::UInt
+//
+// is typedef-ed to be unsigned int (unsigned integer made up of 4
+// bytes).
+//
+// Such functionality should belong to STL, but I cannot find it
+// there.
+//
+// Google Test uses this class in the implementation of floating-point
+// comparison.
+//
+// For now it only handles UInt (unsigned int) as that's all Google Test
+// needs.  Other types can be easily added in the future if need
+// arises.
+template <size_t size>
+class TypeWithSize {
+ public:
+  // This prevents the user from using TypeWithSize<N> with incorrect
+  // values of N.
+  typedef void UInt;
+};
+
+// The specialization for size 4.
+template <>
+class TypeWithSize<4> {
+ public:
+  // unsigned int has size 4 in both gcc and MSVC.
+  //
+  // As base/basictypes.h doesn't compile on Windows, we cannot use
+  // uint32, uint64, and etc here.
+  typedef int Int;
+  typedef unsigned int UInt;
+};
+
+// The specialization for size 8.
+template <>
+class TypeWithSize<8> {
+ public:
+#if GTEST_OS_WINDOWS
+  typedef __int64 Int;
+  typedef unsigned __int64 UInt;
+#else
+  typedef long long Int;  // NOLINT
+  typedef unsigned long long UInt;  // NOLINT
+#endif  // GTEST_OS_WINDOWS
+};
+
+// Integer types of known sizes.
+typedef TypeWithSize<4>::Int Int32;
+typedef TypeWithSize<4>::UInt UInt32;
+typedef TypeWithSize<8>::Int Int64;
+typedef TypeWithSize<8>::UInt UInt64;
+typedef TypeWithSize<8>::Int TimeInMillis;  // Represents time in milliseconds.
+
+// Utilities for command line flags and environment variables.
+
+// Macro for referencing flags.
+#define GTEST_FLAG(name) FLAGS_gtest_##name
+
+// Macros for declaring flags.
+#define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name)
+#define GTEST_DECLARE_int32_(name) \
+    GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name)
+#define GTEST_DECLARE_string_(name) \
+    GTEST_API_ extern ::testing::internal::String GTEST_FLAG(name)
+
+// Macros for defining flags.
+#define GTEST_DEFINE_bool_(name, default_val, doc) \
+    GTEST_API_ bool GTEST_FLAG(name) = (default_val)
+#define GTEST_DEFINE_int32_(name, default_val, doc) \
+    GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val)
+#define GTEST_DEFINE_string_(name, default_val, doc) \
+    GTEST_API_ ::testing::internal::String GTEST_FLAG(name) = (default_val)
+
+// Parses 'str' for a 32-bit signed integer.  If successful, writes the result
+// to *value and returns true; otherwise leaves *value unchanged and returns
+// false.
+// TODO(chandlerc): Find a better way to refactor flag and environment parsing
+// out of both gtest-port.cc and gtest.cc to avoid exporting this utility
+// function.
+bool ParseInt32(const Message& src_text, const char* str, Int32* value);
+
+// Parses a bool/Int32/string from the environment variable
+// corresponding to the given Google Test flag.
+bool BoolFromGTestEnv(const char* flag, bool default_val);
+GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val);
+const char* StringFromGTestEnv(const char* flag, const char* default_val);
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
diff --git a/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-string.h b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-string.h
new file mode 100644
index 0000000..aff093de
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-string.h
@@ -0,0 +1,350 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file declares the String class and functions used internally by
+// Google Test.  They are subject to change without notice. They should not used
+// by code external to Google Test.
+//
+// This header file is #included by <gtest/internal/gtest-internal.h>.
+// It should not be #included by other files.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
+
+#ifdef __BORLANDC__
+// string.h is not guaranteed to provide strcpy on C++ Builder.
+#include <mem.h>
+#endif
+
+#include <string.h>
+#include <gtest/internal/gtest-port.h>
+
+#include <string>
+
+namespace testing {
+namespace internal {
+
+// String - a UTF-8 string class.
+//
+// For historic reasons, we don't use std::string.
+//
+// TODO(wan@google.com): replace this class with std::string or
+// implement it in terms of the latter.
+//
+// Note that String can represent both NULL and the empty string,
+// while std::string cannot represent NULL.
+//
+// NULL and the empty string are considered different.  NULL is less
+// than anything (including the empty string) except itself.
+//
+// This class only provides minimum functionality necessary for
+// implementing Google Test.  We do not intend to implement a full-fledged
+// string class here.
+//
+// Since the purpose of this class is to provide a substitute for
+// std::string on platforms where it cannot be used, we define a copy
+// constructor and assignment operators such that we don't need
+// conditional compilation in a lot of places.
+//
+// In order to make the representation efficient, the d'tor of String
+// is not virtual.  Therefore DO NOT INHERIT FROM String.
+class GTEST_API_ String {
+ public:
+  // Static utility methods
+
+  // Returns the input enclosed in double quotes if it's not NULL;
+  // otherwise returns "(null)".  For example, "\"Hello\"" is returned
+  // for input "Hello".
+  //
+  // This is useful for printing a C string in the syntax of a literal.
+  //
+  // Known issue: escape sequences are not handled yet.
+  static String ShowCStringQuoted(const char* c_str);
+
+  // Clones a 0-terminated C string, allocating memory using new.  The
+  // caller is responsible for deleting the return value using
+  // delete[].  Returns the cloned string, or NULL if the input is
+  // NULL.
+  //
+  // This is different from strdup() in string.h, which allocates
+  // memory using malloc().
+  static const char* CloneCString(const char* c_str);
+
+#if GTEST_OS_WINDOWS_MOBILE
+  // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be
+  // able to pass strings to Win32 APIs on CE we need to convert them
+  // to 'Unicode', UTF-16.
+
+  // Creates a UTF-16 wide string from the given ANSI string, allocating
+  // memory using new. The caller is responsible for deleting the return
+  // value using delete[]. Returns the wide string, or NULL if the
+  // input is NULL.
+  //
+  // The wide string is created using the ANSI codepage (CP_ACP) to
+  // match the behaviour of the ANSI versions of Win32 calls and the
+  // C runtime.
+  static LPCWSTR AnsiToUtf16(const char* c_str);
+
+  // Creates an ANSI string from the given wide string, allocating
+  // memory using new. The caller is responsible for deleting the return
+  // value using delete[]. Returns the ANSI string, or NULL if the
+  // input is NULL.
+  //
+  // The returned string is created using the ANSI codepage (CP_ACP) to
+  // match the behaviour of the ANSI versions of Win32 calls and the
+  // C runtime.
+  static const char* Utf16ToAnsi(LPCWSTR utf16_str);
+#endif
+
+  // Compares two C strings.  Returns true iff they have the same content.
+  //
+  // Unlike strcmp(), this function can handle NULL argument(s).  A
+  // NULL C string is considered different to any non-NULL C string,
+  // including the empty string.
+  static bool CStringEquals(const char* lhs, const char* rhs);
+
+  // Converts a wide C string to a String using the UTF-8 encoding.
+  // NULL will be converted to "(null)".  If an error occurred during
+  // the conversion, "(failed to convert from wide string)" is
+  // returned.
+  static String ShowWideCString(const wchar_t* wide_c_str);
+
+  // Similar to ShowWideCString(), except that this function encloses
+  // the converted string in double quotes.
+  static String ShowWideCStringQuoted(const wchar_t* wide_c_str);
+
+  // Compares two wide C strings.  Returns true iff they have the same
+  // content.
+  //
+  // Unlike wcscmp(), this function can handle NULL argument(s).  A
+  // NULL C string is considered different to any non-NULL C string,
+  // including the empty string.
+  static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);
+
+  // Compares two C strings, ignoring case.  Returns true iff they
+  // have the same content.
+  //
+  // Unlike strcasecmp(), this function can handle NULL argument(s).
+  // A NULL C string is considered different to any non-NULL C string,
+  // including the empty string.
+  static bool CaseInsensitiveCStringEquals(const char* lhs,
+                                           const char* rhs);
+
+  // Compares two wide C strings, ignoring case.  Returns true iff they
+  // have the same content.
+  //
+  // Unlike wcscasecmp(), this function can handle NULL argument(s).
+  // A NULL C string is considered different to any non-NULL wide C string,
+  // including the empty string.
+  // NB: The implementations on different platforms slightly differ.
+  // On windows, this method uses _wcsicmp which compares according to LC_CTYPE
+  // environment variable. On GNU platform this method uses wcscasecmp
+  // which compares according to LC_CTYPE category of the current locale.
+  // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
+  // current locale.
+  static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
+                                               const wchar_t* rhs);
+
+  // Formats a list of arguments to a String, using the same format
+  // spec string as for printf.
+  //
+  // We do not use the StringPrintf class as it is not universally
+  // available.
+  //
+  // The result is limited to 4096 characters (including the tailing
+  // 0).  If 4096 characters are not enough to format the input,
+  // "<buffer exceeded>" is returned.
+  static String Format(const char* format, ...);
+
+  // C'tors
+
+  // The default c'tor constructs a NULL string.
+  String() : c_str_(NULL), length_(0) {}
+
+  // Constructs a String by cloning a 0-terminated C string.
+  String(const char* a_c_str) {  // NOLINT
+    if (a_c_str == NULL) {
+      c_str_ = NULL;
+      length_ = 0;
+    } else {
+      ConstructNonNull(a_c_str, strlen(a_c_str));
+    }
+  }
+
+  // Constructs a String by copying a given number of chars from a
+  // buffer.  E.g. String("hello", 3) creates the string "hel",
+  // String("a\0bcd", 4) creates "a\0bc", String(NULL, 0) creates "",
+  // and String(NULL, 1) results in access violation.
+  String(const char* buffer, size_t a_length) {
+    ConstructNonNull(buffer, a_length);
+  }
+
+  // The copy c'tor creates a new copy of the string.  The two
+  // String objects do not share content.
+  String(const String& str) : c_str_(NULL), length_(0) { *this = str; }
+
+  // D'tor.  String is intended to be a final class, so the d'tor
+  // doesn't need to be virtual.
+  ~String() { delete[] c_str_; }
+
+  // Allows a String to be implicitly converted to an ::std::string or
+  // ::string, and vice versa.  Converting a String containing a NULL
+  // pointer to ::std::string or ::string is undefined behavior.
+  // Converting a ::std::string or ::string containing an embedded NUL
+  // character to a String will result in the prefix up to the first
+  // NUL character.
+  String(const ::std::string& str) {
+    ConstructNonNull(str.c_str(), str.length());
+  }
+
+  operator ::std::string() const { return ::std::string(c_str(), length()); }
+
+#if GTEST_HAS_GLOBAL_STRING
+  String(const ::string& str) {
+    ConstructNonNull(str.c_str(), str.length());
+  }
+
+  operator ::string() const { return ::string(c_str(), length()); }
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+  // Returns true iff this is an empty string (i.e. "").
+  bool empty() const { return (c_str() != NULL) && (length() == 0); }
+
+  // Compares this with another String.
+  // Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0
+  // if this is greater than rhs.
+  int Compare(const String& rhs) const;
+
+  // Returns true iff this String equals the given C string.  A NULL
+  // string and a non-NULL string are considered not equal.
+  bool operator==(const char* a_c_str) const { return Compare(a_c_str) == 0; }
+
+  // Returns true iff this String is less than the given String.  A
+  // NULL string is considered less than "".
+  bool operator<(const String& rhs) const { return Compare(rhs) < 0; }
+
+  // Returns true iff this String doesn't equal the given C string.  A NULL
+  // string and a non-NULL string are considered not equal.
+  bool operator!=(const char* a_c_str) const { return !(*this == a_c_str); }
+
+  // Returns true iff this String ends with the given suffix.  *Any*
+  // String is considered to end with a NULL or empty suffix.
+  bool EndsWith(const char* suffix) const;
+
+  // Returns true iff this String ends with the given suffix, not considering
+  // case. Any String is considered to end with a NULL or empty suffix.
+  bool EndsWithCaseInsensitive(const char* suffix) const;
+
+  // Returns the length of the encapsulated string, or 0 if the
+  // string is NULL.
+  size_t length() const { return length_; }
+
+  // Gets the 0-terminated C string this String object represents.
+  // The String object still owns the string.  Therefore the caller
+  // should NOT delete the return value.
+  const char* c_str() const { return c_str_; }
+
+  // Assigns a C string to this object.  Self-assignment works.
+  const String& operator=(const char* a_c_str) {
+    return *this = String(a_c_str);
+  }
+
+  // Assigns a String object to this object.  Self-assignment works.
+  const String& operator=(const String& rhs) {
+    if (this != &rhs) {
+      delete[] c_str_;
+      if (rhs.c_str() == NULL) {
+        c_str_ = NULL;
+        length_ = 0;
+      } else {
+        ConstructNonNull(rhs.c_str(), rhs.length());
+      }
+    }
+
+    return *this;
+  }
+
+ private:
+  // Constructs a non-NULL String from the given content.  This
+  // function can only be called when data_ has not been allocated.
+  // ConstructNonNull(NULL, 0) results in an empty string ("").
+  // ConstructNonNull(NULL, non_zero) is undefined behavior.
+  void ConstructNonNull(const char* buffer, size_t a_length) {
+    char* const str = new char[a_length + 1];
+    memcpy(str, buffer, a_length);
+    str[a_length] = '\0';
+    c_str_ = str;
+    length_ = a_length;
+  }
+
+  const char* c_str_;
+  size_t length_;
+};  // class String
+
+// Streams a String to an ostream.  Each '\0' character in the String
+// is replaced with "\\0".
+inline ::std::ostream& operator<<(::std::ostream& os, const String& str) {
+  if (str.c_str() == NULL) {
+    os << "(null)";
+  } else {
+    const char* const c_str = str.c_str();
+    for (size_t i = 0; i != str.length(); i++) {
+      if (c_str[i] == '\0') {
+        os << "\\0";
+      } else {
+        os << c_str[i];
+      }
+    }
+  }
+  return os;
+}
+
+// Gets the content of the StrStream's buffer as a String.  Each '\0'
+// character in the buffer is replaced with "\\0".
+GTEST_API_ String StrStreamToString(StrStream* stream);
+
+// Converts a streamable value to a String.  A NULL pointer is
+// converted to "(null)".  When the input value is a ::string,
+// ::std::string, ::wstring, or ::std::wstring object, each NUL
+// character in it is replaced with "\\0".
+
+// Declared here but defined in gtest.h, so that it has access
+// to the definition of the Message class, required by the ARM
+// compiler.
+template <typename T>
+String StreamableToString(const T& streamable);
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
diff --git a/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-tuple.h b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-tuple.h
new file mode 100644
index 0000000..16178fc
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-tuple.h
@@ -0,0 +1,968 @@
+// This file was GENERATED by a script.  DO NOT EDIT BY HAND!!!
+
+// Copyright 2009 Google Inc.
+// All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Implements a subset of TR1 tuple needed by Google Test and Google Mock.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
+
+#include <utility>  // For ::std::pair.
+
+// The compiler used in Symbian has a bug that prevents us from declaring the
+// tuple template as a friend (it complains that tuple is redefined).  This
+// hack bypasses the bug by declaring the members that should otherwise be
+// private as public.
+// Sun Studio versions < 12 also have the above bug.
+#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
+#define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
+#else
+#define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
+    template <GTEST_10_TYPENAMES_(U)> friend class tuple; \
+   private:
+#endif
+
+// GTEST_n_TUPLE_(T) is the type of an n-tuple.
+#define GTEST_0_TUPLE_(T) tuple<>
+#define GTEST_1_TUPLE_(T) tuple<T##0, void, void, void, void, void, void, \
+    void, void, void>
+#define GTEST_2_TUPLE_(T) tuple<T##0, T##1, void, void, void, void, void, \
+    void, void, void>
+#define GTEST_3_TUPLE_(T) tuple<T##0, T##1, T##2, void, void, void, void, \
+    void, void, void>
+#define GTEST_4_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, void, void, void, \
+    void, void, void>
+#define GTEST_5_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, void, void, \
+    void, void, void>
+#define GTEST_6_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, void, \
+    void, void, void>
+#define GTEST_7_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+    void, void, void>
+#define GTEST_8_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+    T##7, void, void>
+#define GTEST_9_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+    T##7, T##8, void>
+#define GTEST_10_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+    T##7, T##8, T##9>
+
+// GTEST_n_TYPENAMES_(T) declares a list of n typenames.
+#define GTEST_0_TYPENAMES_(T)
+#define GTEST_1_TYPENAMES_(T) typename T##0
+#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1
+#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2
+#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3
+#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4
+#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4, typename T##5
+#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4, typename T##5, typename T##6
+#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4, typename T##5, typename T##6, typename T##7
+#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4, typename T##5, typename T##6, \
+    typename T##7, typename T##8
+#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4, typename T##5, typename T##6, \
+    typename T##7, typename T##8, typename T##9
+
+// In theory, defining stuff in the ::std namespace is undefined
+// behavior.  We can do this as we are playing the role of a standard
+// library vendor.
+namespace std {
+namespace tr1 {
+
+template <typename T0 = void, typename T1 = void, typename T2 = void,
+    typename T3 = void, typename T4 = void, typename T5 = void,
+    typename T6 = void, typename T7 = void, typename T8 = void,
+    typename T9 = void>
+class tuple;
+
+// Anything in namespace gtest_internal is Google Test's INTERNAL
+// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.
+namespace gtest_internal {
+
+// ByRef<T>::type is T if T is a reference; otherwise it's const T&.
+template <typename T>
+struct ByRef { typedef const T& type; };  // NOLINT
+template <typename T>
+struct ByRef<T&> { typedef T& type; };  // NOLINT
+
+// A handy wrapper for ByRef.
+#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
+
+// AddRef<T>::type is T if T is a reference; otherwise it's T&.  This
+// is the same as tr1::add_reference<T>::type.
+template <typename T>
+struct AddRef { typedef T& type; };  // NOLINT
+template <typename T>
+struct AddRef<T&> { typedef T& type; };  // NOLINT
+
+// A handy wrapper for AddRef.
+#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
+
+// A helper for implementing get<k>().
+template <int k> class Get;
+
+// A helper for implementing tuple_element<k, T>.  kIndexValid is true
+// iff k < the number of fields in tuple type T.
+template <bool kIndexValid, int kIndex, class Tuple>
+struct TupleElement;
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 0, GTEST_10_TUPLE_(T)> { typedef T0 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 1, GTEST_10_TUPLE_(T)> { typedef T1 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 2, GTEST_10_TUPLE_(T)> { typedef T2 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 3, GTEST_10_TUPLE_(T)> { typedef T3 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 4, GTEST_10_TUPLE_(T)> { typedef T4 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 5, GTEST_10_TUPLE_(T)> { typedef T5 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 6, GTEST_10_TUPLE_(T)> { typedef T6 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 7, GTEST_10_TUPLE_(T)> { typedef T7 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 8, GTEST_10_TUPLE_(T)> { typedef T8 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 9, GTEST_10_TUPLE_(T)> { typedef T9 type; };
+
+}  // namespace gtest_internal
+
+template <>
+class tuple<> {
+ public:
+  tuple() {}
+  tuple(const tuple& /* t */)  {}
+  tuple& operator=(const tuple& /* t */) { return *this; }
+};
+
+template <GTEST_1_TYPENAMES_(T)>
+class GTEST_1_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {}
+
+  tuple(const tuple& t) : f0_(t.f0_) {}
+
+  template <GTEST_1_TYPENAMES_(U)>
+  tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_1_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_1_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_1_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    return *this;
+  }
+
+  T0 f0_;
+};
+
+template <GTEST_2_TYPENAMES_(T)>
+class GTEST_2_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0),
+      f1_(f1) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {}
+
+  template <GTEST_2_TYPENAMES_(U)>
+  tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {}
+  template <typename U0, typename U1>
+  tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_2_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_2_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+  template <typename U0, typename U1>
+  tuple& operator=(const ::std::pair<U0, U1>& p) {
+    f0_ = p.first;
+    f1_ = p.second;
+    return *this;
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_2_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+};
+
+template <GTEST_3_TYPENAMES_(T)>
+class GTEST_3_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}
+
+  template <GTEST_3_TYPENAMES_(U)>
+  tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_3_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_3_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_3_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+};
+
+template <GTEST_4_TYPENAMES_(T)>
+class GTEST_4_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2),
+      f3_(f3) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {}
+
+  template <GTEST_4_TYPENAMES_(U)>
+  tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_4_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_4_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_4_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+};
+
+template <GTEST_5_TYPENAMES_(T)>
+class GTEST_5_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3,
+      GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_) {}
+
+  template <GTEST_5_TYPENAMES_(U)>
+  tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_5_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_5_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_5_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+};
+
+template <GTEST_6_TYPENAMES_(T)>
+class GTEST_6_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+      GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
+      f5_(f5) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_), f5_(t.f5_) {}
+
+  template <GTEST_6_TYPENAMES_(U)>
+  tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_6_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_6_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_6_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    f5_ = t.f5_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+  T5 f5_;
+};
+
+template <GTEST_7_TYPENAMES_(T)>
+class GTEST_7_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2),
+      f3_(f3), f4_(f4), f5_(f5), f6_(f6) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}
+
+  template <GTEST_7_TYPENAMES_(U)>
+  tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_7_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_7_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_7_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    f5_ = t.f5_;
+    f6_ = t.f6_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+  T5 f5_;
+  T6 f6_;
+};
+
+template <GTEST_8_TYPENAMES_(T)>
+class GTEST_8_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6,
+      GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
+      f5_(f5), f6_(f6), f7_(f7) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}
+
+  template <GTEST_8_TYPENAMES_(U)>
+  tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_8_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_8_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_8_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    f5_ = t.f5_;
+    f6_ = t.f6_;
+    f7_ = t.f7_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+  T5 f5_;
+  T6 f6_;
+  T7 f7_;
+};
+
+template <GTEST_9_TYPENAMES_(T)>
+class GTEST_9_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,
+      GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
+      f5_(f5), f6_(f6), f7_(f7), f8_(f8) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}
+
+  template <GTEST_9_TYPENAMES_(U)>
+  tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_9_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_9_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_9_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    f5_ = t.f5_;
+    f6_ = t.f6_;
+    f7_ = t.f7_;
+    f8_ = t.f8_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+  T5 f5_;
+  T6 f6_;
+  T7 f7_;
+  T8 f8_;
+};
+
+template <GTEST_10_TYPENAMES_(T)>
+class tuple {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(),
+      f9_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,
+      GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2),
+      f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {}
+
+  template <GTEST_10_TYPENAMES_(U)>
+  tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_),
+      f9_(t.f9_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_10_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_10_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_10_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    f5_ = t.f5_;
+    f6_ = t.f6_;
+    f7_ = t.f7_;
+    f8_ = t.f8_;
+    f9_ = t.f9_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+  T5 f5_;
+  T6 f6_;
+  T7 f7_;
+  T8 f8_;
+  T9 f9_;
+};
+
+// 6.1.3.2 Tuple creation functions.
+
+// Known limitations: we don't support passing an
+// std::tr1::reference_wrapper<T> to make_tuple().  And we don't
+// implement tie().
+
+inline tuple<> make_tuple() { return tuple<>(); }
+
+template <GTEST_1_TYPENAMES_(T)>
+inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) {
+  return GTEST_1_TUPLE_(T)(f0);
+}
+
+template <GTEST_2_TYPENAMES_(T)>
+inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) {
+  return GTEST_2_TUPLE_(T)(f0, f1);
+}
+
+template <GTEST_3_TYPENAMES_(T)>
+inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) {
+  return GTEST_3_TUPLE_(T)(f0, f1, f2);
+}
+
+template <GTEST_4_TYPENAMES_(T)>
+inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3) {
+  return GTEST_4_TUPLE_(T)(f0, f1, f2, f3);
+}
+
+template <GTEST_5_TYPENAMES_(T)>
+inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4) {
+  return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4);
+}
+
+template <GTEST_6_TYPENAMES_(T)>
+inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4, const T5& f5) {
+  return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5);
+}
+
+template <GTEST_7_TYPENAMES_(T)>
+inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4, const T5& f5, const T6& f6) {
+  return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6);
+}
+
+template <GTEST_8_TYPENAMES_(T)>
+inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) {
+  return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7);
+}
+
+template <GTEST_9_TYPENAMES_(T)>
+inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,
+    const T8& f8) {
+  return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8);
+}
+
+template <GTEST_10_TYPENAMES_(T)>
+inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,
+    const T8& f8, const T9& f9) {
+  return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9);
+}
+
+// 6.1.3.3 Tuple helper classes.
+
+template <typename Tuple> struct tuple_size;
+
+template <GTEST_0_TYPENAMES_(T)>
+struct tuple_size<GTEST_0_TUPLE_(T)> { static const int value = 0; };
+
+template <GTEST_1_TYPENAMES_(T)>
+struct tuple_size<GTEST_1_TUPLE_(T)> { static const int value = 1; };
+
+template <GTEST_2_TYPENAMES_(T)>
+struct tuple_size<GTEST_2_TUPLE_(T)> { static const int value = 2; };
+
+template <GTEST_3_TYPENAMES_(T)>
+struct tuple_size<GTEST_3_TUPLE_(T)> { static const int value = 3; };
+
+template <GTEST_4_TYPENAMES_(T)>
+struct tuple_size<GTEST_4_TUPLE_(T)> { static const int value = 4; };
+
+template <GTEST_5_TYPENAMES_(T)>
+struct tuple_size<GTEST_5_TUPLE_(T)> { static const int value = 5; };
+
+template <GTEST_6_TYPENAMES_(T)>
+struct tuple_size<GTEST_6_TUPLE_(T)> { static const int value = 6; };
+
+template <GTEST_7_TYPENAMES_(T)>
+struct tuple_size<GTEST_7_TUPLE_(T)> { static const int value = 7; };
+
+template <GTEST_8_TYPENAMES_(T)>
+struct tuple_size<GTEST_8_TUPLE_(T)> { static const int value = 8; };
+
+template <GTEST_9_TYPENAMES_(T)>
+struct tuple_size<GTEST_9_TUPLE_(T)> { static const int value = 9; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct tuple_size<GTEST_10_TUPLE_(T)> { static const int value = 10; };
+
+template <int k, class Tuple>
+struct tuple_element {
+  typedef typename gtest_internal::TupleElement<
+      k < (tuple_size<Tuple>::value), k, Tuple>::type type;
+};
+
+#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
+
+// 6.1.3.4 Element access.
+
+namespace gtest_internal {
+
+template <>
+class Get<0> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))
+  Field(Tuple& t) { return t.f0_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))
+  ConstField(const Tuple& t) { return t.f0_; }
+};
+
+template <>
+class Get<1> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))
+  Field(Tuple& t) { return t.f1_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))
+  ConstField(const Tuple& t) { return t.f1_; }
+};
+
+template <>
+class Get<2> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))
+  Field(Tuple& t) { return t.f2_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))
+  ConstField(const Tuple& t) { return t.f2_; }
+};
+
+template <>
+class Get<3> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))
+  Field(Tuple& t) { return t.f3_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))
+  ConstField(const Tuple& t) { return t.f3_; }
+};
+
+template <>
+class Get<4> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))
+  Field(Tuple& t) { return t.f4_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))
+  ConstField(const Tuple& t) { return t.f4_; }
+};
+
+template <>
+class Get<5> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))
+  Field(Tuple& t) { return t.f5_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))
+  ConstField(const Tuple& t) { return t.f5_; }
+};
+
+template <>
+class Get<6> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))
+  Field(Tuple& t) { return t.f6_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))
+  ConstField(const Tuple& t) { return t.f6_; }
+};
+
+template <>
+class Get<7> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))
+  Field(Tuple& t) { return t.f7_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))
+  ConstField(const Tuple& t) { return t.f7_; }
+};
+
+template <>
+class Get<8> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))
+  Field(Tuple& t) { return t.f8_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))
+  ConstField(const Tuple& t) { return t.f8_; }
+};
+
+template <>
+class Get<9> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))
+  Field(Tuple& t) { return t.f9_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))
+  ConstField(const Tuple& t) { return t.f9_; }
+};
+
+}  // namespace gtest_internal
+
+template <int k, GTEST_10_TYPENAMES_(T)>
+GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T)))
+get(GTEST_10_TUPLE_(T)& t) {
+  return gtest_internal::Get<k>::Field(t);
+}
+
+template <int k, GTEST_10_TYPENAMES_(T)>
+GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k,  GTEST_10_TUPLE_(T)))
+get(const GTEST_10_TUPLE_(T)& t) {
+  return gtest_internal::Get<k>::ConstField(t);
+}
+
+// 6.1.3.5 Relational operators
+
+// We only implement == and !=, as we don't have a need for the rest yet.
+
+namespace gtest_internal {
+
+// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the
+// first k fields of t1 equals the first k fields of t2.
+// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if
+// k1 != k2.
+template <int kSize1, int kSize2>
+struct SameSizeTuplePrefixComparator;
+
+template <>
+struct SameSizeTuplePrefixComparator<0, 0> {
+  template <class Tuple1, class Tuple2>
+  static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
+    return true;
+  }
+};
+
+template <int k>
+struct SameSizeTuplePrefixComparator<k, k> {
+  template <class Tuple1, class Tuple2>
+  static bool Eq(const Tuple1& t1, const Tuple2& t2) {
+    return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&
+        ::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);
+  }
+};
+
+}  // namespace gtest_internal
+
+template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
+inline bool operator==(const GTEST_10_TUPLE_(T)& t,
+                       const GTEST_10_TUPLE_(U)& u) {
+  return gtest_internal::SameSizeTuplePrefixComparator<
+      tuple_size<GTEST_10_TUPLE_(T)>::value,
+      tuple_size<GTEST_10_TUPLE_(U)>::value>::Eq(t, u);
+}
+
+template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
+inline bool operator!=(const GTEST_10_TUPLE_(T)& t,
+                       const GTEST_10_TUPLE_(U)& u) { return !(t == u); }
+
+// 6.1.4 Pairs.
+// Unimplemented.
+
+}  // namespace tr1
+}  // namespace std
+
+#undef GTEST_0_TUPLE_
+#undef GTEST_1_TUPLE_
+#undef GTEST_2_TUPLE_
+#undef GTEST_3_TUPLE_
+#undef GTEST_4_TUPLE_
+#undef GTEST_5_TUPLE_
+#undef GTEST_6_TUPLE_
+#undef GTEST_7_TUPLE_
+#undef GTEST_8_TUPLE_
+#undef GTEST_9_TUPLE_
+#undef GTEST_10_TUPLE_
+
+#undef GTEST_0_TYPENAMES_
+#undef GTEST_1_TYPENAMES_
+#undef GTEST_2_TYPENAMES_
+#undef GTEST_3_TYPENAMES_
+#undef GTEST_4_TYPENAMES_
+#undef GTEST_5_TYPENAMES_
+#undef GTEST_6_TYPENAMES_
+#undef GTEST_7_TYPENAMES_
+#undef GTEST_8_TYPENAMES_
+#undef GTEST_9_TYPENAMES_
+#undef GTEST_10_TYPENAMES_
+
+#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
+#undef GTEST_BY_REF_
+#undef GTEST_ADD_REF_
+#undef GTEST_TUPLE_ELEMENT_
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
diff --git a/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h
new file mode 100644
index 0000000..093eee6
--- /dev/null
+++ b/src/LLVM/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h
@@ -0,0 +1,3321 @@
+// This file was GENERATED by command:
+//     pump.py gtest-type-util.h.pump
+// DO NOT EDIT BY HAND!!!
+
+// Copyright 2008 Google Inc.
+// All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Type utilities needed for implementing typed and type-parameterized
+// tests.  This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!
+//
+// Currently we support at most 50 types in a list, and at most 50
+// type-parameterized tests in one type-parameterized test case.
+// Please contact googletestframework@googlegroups.com if you need
+// more.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
+
+#include <gtest/internal/gtest-port.h>
+#include <gtest/internal/gtest-string.h>
+
+#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+// #ifdef __GNUC__ is too general here.  It is possible to use gcc without using
+// libstdc++ (which is where cxxabi.h comes from).
+#ifdef __GLIBCXX__
+#include <cxxabi.h>
+#endif  // __GLIBCXX__
+
+namespace testing {
+namespace internal {
+
+// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same
+// type.  This can be used as a compile-time assertion to ensure that
+// two types are equal.
+
+template <typename T1, typename T2>
+struct AssertTypeEq;
+
+template <typename T>
+struct AssertTypeEq<T, T> {
+  typedef bool type;
+};
+
+// GetTypeName<T>() returns a human-readable name of type T.
+template <typename T>
+String GetTypeName() {
+#if GTEST_HAS_RTTI
+
+  const char* const name = typeid(T).name();
+#ifdef __GLIBCXX__
+  int status = 0;
+  // gcc's implementation of typeid(T).name() mangles the type name,
+  // so we have to demangle it.
+  char* const readable_name = abi::__cxa_demangle(name, 0, 0, &status);
+  const String name_str(status == 0 ? readable_name : name);
+  free(readable_name);
+  return name_str;
+#else
+  return name;
+#endif  // __GLIBCXX__
+
+#else
+  return "<type>";
+#endif  // GTEST_HAS_RTTI
+}
+
+// A unique type used as the default value for the arguments of class
+// template Types.  This allows us to simulate variadic templates
+// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't
+// support directly.
+struct None {};
+
+// The following family of struct and struct templates are used to
+// represent type lists.  In particular, TypesN<T1, T2, ..., TN>
+// represents a type list with N types (T1, T2, ..., and TN) in it.
+// Except for Types0, every struct in the family has two member types:
+// Head for the first type in the list, and Tail for the rest of the
+// list.
+
+// The empty type list.
+struct Types0 {};
+
+// Type lists of length 1, 2, 3, and so on.
+
+template <typename T1>
+struct Types1 {
+  typedef T1 Head;
+  typedef Types0 Tail;
+};
+template <typename T1, typename T2>
+struct Types2 {
+  typedef T1 Head;
+  typedef Types1<T2> Tail;
+};
+
+template <typename T1, typename T2, typename T3>
+struct Types3 {
+  typedef T1 Head;
+  typedef Types2<T2, T3> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4>
+struct Types4 {
+  typedef T1 Head;
+  typedef Types3<T2, T3, T4> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+struct Types5 {
+  typedef T1 Head;
+  typedef Types4<T2, T3, T4, T5> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6>
+struct Types6 {
+  typedef T1 Head;
+  typedef Types5<T2, T3, T4, T5, T6> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7>
+struct Types7 {
+  typedef T1 Head;
+  typedef Types6<T2, T3, T4, T5, T6, T7> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8>
+struct Types8 {
+  typedef T1 Head;
+  typedef Types7<T2, T3, T4, T5, T6, T7, T8> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9>
+struct Types9 {
+  typedef T1 Head;
+  typedef Types8<T2, T3, T4, T5, T6, T7, T8, T9> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10>
+struct Types10 {
+  typedef T1 Head;
+  typedef Types9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11>
+struct Types11 {
+  typedef T1 Head;
+  typedef Types10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12>
+struct Types12 {
+  typedef T1 Head;
+  typedef Types11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13>
+struct Types13 {
+  typedef T1 Head;
+  typedef Types12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14>
+struct Types14 {
+  typedef T1 Head;
+  typedef Types13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15>
+struct Types15 {
+  typedef T1 Head;
+  typedef Types14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16>
+struct Types16 {
+  typedef T1 Head;
+  typedef Types15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17>
+struct Types17 {
+  typedef T1 Head;
+  typedef Types16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18>
+struct Types18 {
+  typedef T1 Head;
+  typedef Types17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19>
+struct Types19 {
+  typedef T1 Head;
+  typedef Types18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20>
+struct Types20 {
+  typedef T1 Head;
+  typedef Types19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21>
+struct Types21 {
+  typedef T1 Head;
+  typedef Types20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22>
+struct Types22 {
+  typedef T1 Head;
+  typedef Types21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23>
+struct Types23 {
+  typedef T1 Head;
+  typedef Types22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24>
+struct Types24 {
+  typedef T1 Head;
+  typedef Types23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25>
+struct Types25 {
+  typedef T1 Head;
+  typedef Types24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26>
+struct Types26 {
+  typedef T1 Head;
+  typedef Types25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27>
+struct Types27 {
+  typedef T1 Head;
+  typedef Types26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28>
+struct Types28 {
+  typedef T1 Head;
+  typedef Types27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29>
+struct Types29 {
+  typedef T1 Head;
+  typedef Types28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30>
+struct Types30 {
+  typedef T1 Head;
+  typedef Types29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31>
+struct Types31 {
+  typedef T1 Head;
+  typedef Types30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32>
+struct Types32 {
+  typedef T1 Head;
+  typedef Types31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33>
+struct Types33 {
+  typedef T1 Head;
+  typedef Types32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34>
+struct Types34 {
+  typedef T1 Head;
+  typedef Types33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35>
+struct Types35 {
+  typedef T1 Head;
+  typedef Types34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36>
+struct Types36 {
+  typedef T1 Head;
+  typedef Types35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37>
+struct Types37 {
+  typedef T1 Head;
+  typedef Types36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38>
+struct Types38 {
+  typedef T1 Head;
+  typedef Types37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39>
+struct Types39 {
+  typedef T1 Head;
+  typedef Types38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40>
+struct Types40 {
+  typedef T1 Head;
+  typedef Types39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41>
+struct Types41 {
+  typedef T1 Head;
+  typedef Types40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42>
+struct Types42 {
+  typedef T1 Head;
+  typedef Types41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43>
+struct Types43 {
+  typedef T1 Head;
+  typedef Types42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44>
+struct Types44 {
+  typedef T1 Head;
+  typedef Types43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45>
+struct Types45 {
+  typedef T1 Head;
+  typedef Types44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46>
+struct Types46 {
+  typedef T1 Head;
+  typedef Types45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45, T46> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47>
+struct Types47 {
+  typedef T1 Head;
+  typedef Types46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45, T46, T47> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48>
+struct Types48 {
+  typedef T1 Head;
+  typedef Types47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45, T46, T47, T48> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49>
+struct Types49 {
+  typedef T1 Head;
+  typedef Types48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45, T46, T47, T48, T49> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49, typename T50>
+struct Types50 {
+  typedef T1 Head;
+  typedef Types49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45, T46, T47, T48, T49, T50> Tail;
+};
+
+
+}  // namespace internal
+
+// We don't want to require the users to write TypesN<...> directly,
+// as that would require them to count the length.  Types<...> is much
+// easier to write, but generates horrible messages when there is a
+// compiler error, as gcc insists on printing out each template
+// argument, even if it has the default value (this means Types<int>
+// will appear as Types<int, None, None, ..., None> in the compiler
+// errors).
+//
+// Our solution is to combine the best part of the two approaches: a
+// user would write Types<T1, ..., TN>, and Google Test will translate
+// that to TypesN<T1, ..., TN> internally to make error messages
+// readable.  The translation is done by the 'type' member of the
+// Types template.
+template <typename T1 = internal::None, typename T2 = internal::None,
+    typename T3 = internal::None, typename T4 = internal::None,
+    typename T5 = internal::None, typename T6 = internal::None,
+    typename T7 = internal::None, typename T8 = internal::None,
+    typename T9 = internal::None, typename T10 = internal::None,
+    typename T11 = internal::None, typename T12 = internal::None,
+    typename T13 = internal::None, typename T14 = internal::None,
+    typename T15 = internal::None, typename T16 = internal::None,
+    typename T17 = internal::None, typename T18 = internal::None,
+    typename T19 = internal::None, typename T20 = internal::None,
+    typename T21 = internal::None, typename T22 = internal::None,
+    typename T23 = internal::None, typename T24 = internal::None,
+    typename T25 = internal::None, typename T26 = internal::None,
+    typename T27 = internal::None, typename T28 = internal::None,
+    typename T29 = internal::None, typename T30 = internal::None,
+    typename T31 = internal::None, typename T32 = internal::None,
+    typename T33 = internal::None, typename T34 = internal::None,
+    typename T35 = internal::None, typename T36 = internal::None,
+    typename T37 = internal::None, typename T38 = internal::None,
+    typename T39 = internal::None, typename T40 = internal::None,
+    typename T41 = internal::None, typename T42 = internal::None,
+    typename T43 = internal::None, typename T44 = internal::None,
+    typename T45 = internal::None, typename T46 = internal::None,
+    typename T47 = internal::None, typename T48 = internal::None,
+    typename T49 = internal::None, typename T50 = internal::None>
+struct Types {
+  typedef internal::Types50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46, T47, T48, T49, T50> type;
+};
+
+template <>
+struct Types<internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types0 type;
+};
+template <typename T1>
+struct Types<T1, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types1<T1> type;
+};
+template <typename T1, typename T2>
+struct Types<T1, T2, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types2<T1, T2> type;
+};
+template <typename T1, typename T2, typename T3>
+struct Types<T1, T2, T3, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types3<T1, T2, T3> type;
+};
+template <typename T1, typename T2, typename T3, typename T4>
+struct Types<T1, T2, T3, T4, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types4<T1, T2, T3, T4> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+struct Types<T1, T2, T3, T4, T5, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types5<T1, T2, T3, T4, T5> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6>
+struct Types<T1, T2, T3, T4, T5, T6, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types6<T1, T2, T3, T4, T5, T6> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7>
+struct Types<T1, T2, T3, T4, T5, T6, T7, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types7<T1, T2, T3, T4, T5, T6, T7> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types8<T1, T2, T3, T4, T5, T6, T7, T8> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+    T46, internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+    T46, T47, internal::None, internal::None, internal::None> {
+  typedef internal::Types47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46, T47> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+    T46, T47, T48, internal::None, internal::None> {
+  typedef internal::Types48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46, T47, T48> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+    T46, T47, T48, T49, internal::None> {
+  typedef internal::Types49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46, T47, T48, T49> type;
+};
+
+namespace internal {
+
+#define GTEST_TEMPLATE_ template <typename T> class
+
+// The template "selector" struct TemplateSel<Tmpl> is used to
+// represent Tmpl, which must be a class template with one type
+// parameter, as a type.  TemplateSel<Tmpl>::Bind<T>::type is defined
+// as the type Tmpl<T>.  This allows us to actually instantiate the
+// template "selected" by TemplateSel<Tmpl>.
+//
+// This trick is necessary for simulating typedef for class templates,
+// which C++ doesn't support directly.
+template <GTEST_TEMPLATE_ Tmpl>
+struct TemplateSel {
+  template <typename T>
+  struct Bind {
+    typedef Tmpl<T> type;
+  };
+};
+
+#define GTEST_BIND_(TmplSel, T) \
+  TmplSel::template Bind<T>::type
+
+// A unique struct template used as the default value for the
+// arguments of class template Templates.  This allows us to simulate
+// variadic templates (e.g. Templates<int>, Templates<int, double>,
+// and etc), which C++ doesn't support directly.
+template <typename T>
+struct NoneT {};
+
+// The following family of struct and struct templates are used to
+// represent template lists.  In particular, TemplatesN<T1, T2, ...,
+// TN> represents a list of N templates (T1, T2, ..., and TN).  Except
+// for Templates0, every struct in the family has two member types:
+// Head for the selector of the first template in the list, and Tail
+// for the rest of the list.
+
+// The empty template list.
+struct Templates0 {};
+
+// Template lists of length 1, 2, 3, and so on.
+
+template <GTEST_TEMPLATE_ T1>
+struct Templates1 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates0 Tail;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2>
+struct Templates2 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates1<T2> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3>
+struct Templates3 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates2<T2, T3> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4>
+struct Templates4 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates3<T2, T3, T4> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5>
+struct Templates5 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates4<T2, T3, T4, T5> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6>
+struct Templates6 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates5<T2, T3, T4, T5, T6> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7>
+struct Templates7 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates6<T2, T3, T4, T5, T6, T7> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8>
+struct Templates8 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates7<T2, T3, T4, T5, T6, T7, T8> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9>
+struct Templates9 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates8<T2, T3, T4, T5, T6, T7, T8, T9> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10>
+struct Templates10 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11>
+struct Templates11 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12>
+struct Templates12 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13>
+struct Templates13 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14>
+struct Templates14 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15>
+struct Templates15 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16>
+struct Templates16 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17>
+struct Templates17 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18>
+struct Templates18 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19>
+struct Templates19 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20>
+struct Templates20 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21>
+struct Templates21 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22>
+struct Templates22 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23>
+struct Templates23 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24>
+struct Templates24 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25>
+struct Templates25 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26>
+struct Templates26 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27>
+struct Templates27 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28>
+struct Templates28 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29>
+struct Templates29 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30>
+struct Templates30 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31>
+struct Templates31 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32>
+struct Templates32 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33>
+struct Templates33 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34>
+struct Templates34 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35>
+struct Templates35 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36>
+struct Templates36 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37>
+struct Templates37 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38>
+struct Templates38 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39>
+struct Templates39 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40>
+struct Templates40 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41>
+struct Templates41 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42>
+struct Templates42 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43>
+struct Templates43 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44>
+struct Templates44 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45>
+struct Templates45 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46>
+struct Templates46 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45, T46> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47>
+struct Templates47 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45, T46, T47> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48>
+struct Templates48 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45, T46, T47, T48> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48,
+    GTEST_TEMPLATE_ T49>
+struct Templates49 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45, T46, T47, T48, T49> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48,
+    GTEST_TEMPLATE_ T49, GTEST_TEMPLATE_ T50>
+struct Templates50 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45, T46, T47, T48, T49, T50> Tail;
+};
+
+
+// We don't want to require the users to write TemplatesN<...> directly,
+// as that would require them to count the length.  Templates<...> is much
+// easier to write, but generates horrible messages when there is a
+// compiler error, as gcc insists on printing out each template
+// argument, even if it has the default value (this means Templates<list>
+// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler
+// errors).
+//
+// Our solution is to combine the best part of the two approaches: a
+// user would write Templates<T1, ..., TN>, and Google Test will translate
+// that to TemplatesN<T1, ..., TN> internally to make error messages
+// readable.  The translation is done by the 'type' member of the
+// Templates template.
+template <GTEST_TEMPLATE_ T1 = NoneT, GTEST_TEMPLATE_ T2 = NoneT,
+    GTEST_TEMPLATE_ T3 = NoneT, GTEST_TEMPLATE_ T4 = NoneT,
+    GTEST_TEMPLATE_ T5 = NoneT, GTEST_TEMPLATE_ T6 = NoneT,
+    GTEST_TEMPLATE_ T7 = NoneT, GTEST_TEMPLATE_ T8 = NoneT,
+    GTEST_TEMPLATE_ T9 = NoneT, GTEST_TEMPLATE_ T10 = NoneT,
+    GTEST_TEMPLATE_ T11 = NoneT, GTEST_TEMPLATE_ T12 = NoneT,
+    GTEST_TEMPLATE_ T13 = NoneT, GTEST_TEMPLATE_ T14 = NoneT,
+    GTEST_TEMPLATE_ T15 = NoneT, GTEST_TEMPLATE_ T16 = NoneT,
+    GTEST_TEMPLATE_ T17 = NoneT, GTEST_TEMPLATE_ T18 = NoneT,
+    GTEST_TEMPLATE_ T19 = NoneT, GTEST_TEMPLATE_ T20 = NoneT,
+    GTEST_TEMPLATE_ T21 = NoneT, GTEST_TEMPLATE_ T22 = NoneT,
+    GTEST_TEMPLATE_ T23 = NoneT, GTEST_TEMPLATE_ T24 = NoneT,
+    GTEST_TEMPLATE_ T25 = NoneT, GTEST_TEMPLATE_ T26 = NoneT,
+    GTEST_TEMPLATE_ T27 = NoneT, GTEST_TEMPLATE_ T28 = NoneT,
+    GTEST_TEMPLATE_ T29 = NoneT, GTEST_TEMPLATE_ T30 = NoneT,
+    GTEST_TEMPLATE_ T31 = NoneT, GTEST_TEMPLATE_ T32 = NoneT,
+    GTEST_TEMPLATE_ T33 = NoneT, GTEST_TEMPLATE_ T34 = NoneT,
+    GTEST_TEMPLATE_ T35 = NoneT, GTEST_TEMPLATE_ T36 = NoneT,
+    GTEST_TEMPLATE_ T37 = NoneT, GTEST_TEMPLATE_ T38 = NoneT,
+    GTEST_TEMPLATE_ T39 = NoneT, GTEST_TEMPLATE_ T40 = NoneT,
+    GTEST_TEMPLATE_ T41 = NoneT, GTEST_TEMPLATE_ T42 = NoneT,
+    GTEST_TEMPLATE_ T43 = NoneT, GTEST_TEMPLATE_ T44 = NoneT,
+    GTEST_TEMPLATE_ T45 = NoneT, GTEST_TEMPLATE_ T46 = NoneT,
+    GTEST_TEMPLATE_ T47 = NoneT, GTEST_TEMPLATE_ T48 = NoneT,
+    GTEST_TEMPLATE_ T49 = NoneT, GTEST_TEMPLATE_ T50 = NoneT>
+struct Templates {
+  typedef Templates50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45, T46, T47, T48, T49, T50> type;
+};
+
+template <>
+struct Templates<NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT> {
+  typedef Templates0 type;
+};
+template <GTEST_TEMPLATE_ T1>
+struct Templates<T1, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT> {
+  typedef Templates1<T1> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2>
+struct Templates<T1, T2, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT> {
+  typedef Templates2<T1, T2> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3>
+struct Templates<T1, T2, T3, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates3<T1, T2, T3> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4>
+struct Templates<T1, T2, T3, T4, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates4<T1, T2, T3, T4> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5>
+struct Templates<T1, T2, T3, T4, T5, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates5<T1, T2, T3, T4, T5> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6>
+struct Templates<T1, T2, T3, T4, T5, T6, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates6<T1, T2, T3, T4, T5, T6> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates7<T1, T2, T3, T4, T5, T6, T7> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates8<T1, T2, T3, T4, T5, T6, T7, T8> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT> {
+  typedef Templates22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT> {
+  typedef Templates23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT> {
+  typedef Templates24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT> {
+  typedef Templates25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT> {
+  typedef Templates26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT> {
+  typedef Templates27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT> {
+  typedef Templates28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT> {
+  typedef Templates29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    T45, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    T45, T46, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45, T46> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    T45, T46, T47, NoneT, NoneT, NoneT> {
+  typedef Templates47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45, T46, T47> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    T45, T46, T47, T48, NoneT, NoneT> {
+  typedef Templates48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45, T46, T47, T48> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48,
+    GTEST_TEMPLATE_ T49>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    T45, T46, T47, T48, T49, NoneT> {
+  typedef Templates49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45, T46, T47, T48, T49> type;
+};
+
+// The TypeList template makes it possible to use either a single type
+// or a Types<...> list in TYPED_TEST_CASE() and
+// INSTANTIATE_TYPED_TEST_CASE_P().
+
+template <typename T>
+struct TypeList { typedef Types1<T> type; };
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49, typename T50>
+struct TypeList<Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46, T47, T48, T49, T50> > {
+  typedef typename Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>::type type;
+};
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
diff --git a/src/LLVM/utils/userloc.pl b/src/LLVM/utils/userloc.pl
new file mode 100644
index 0000000..4da2f40
--- /dev/null
+++ b/src/LLVM/utils/userloc.pl
@@ -0,0 +1,216 @@
+#!/usr/bin/perl -w
+#
+# Program:  userloc.pl
+#
+# Synopsis: This program uses "cvs annotate" to get a summary of how many lines
+#           of code the various developres are responsible for. It takes one
+#           argument, the directory to process. If the argument is not specified
+#           then the cwd is used. The directory must be an LLVM tree checked out
+#           from cvs. 
+#
+# Syntax:   userloc.pl [-tag=tag|-html... <directory>...
+#
+# Options:
+#           -tag=tag
+#               Use "tag" to select the revision (as per cvs -r option)
+#           -filedetails
+#               Report details about lines of code in each file for each user
+#           -html
+#               Generate HTML output instead of text output
+#           -topdir
+#               Specify where the top llvm source directory is. Otherwise the
+#               llvm-config tool is used to find it.
+# Directories:
+#   The directories passed after the options should be relative paths to
+#   directories of interest from the top of the llvm source tree, e.g. "lib"
+#   or "include", etc.
+
+die "Usage userloc.pl [-tag=tag|-html] <directories>..." 
+  if ($#ARGV < 0);
+
+my $tag = "";
+my $html = 0;
+my $debug = 0;
+my $filedetails = "";
+my $srcroot = "";
+while ( defined($ARGV[0]) && substr($ARGV[0],0,1) eq '-' )
+{
+  if ($ARGV[0] =~ /-tag=.*/) {
+    $tag = $ARGV[0];
+    $tag =~ s#-tag=(.*)#$1#;
+  } elsif ($ARGV[0] =~ /-filedetails/) {
+    $filedetails = 1;
+  } elsif ($ARGV[0] eq "-html") {
+    $html = 1;
+  } elsif ($ARGV[0] eq "-debug") {
+    $debug = 1;
+  } elsif ($ARGV[0] eq "-topdir") {
+    shift; $srcroot = $ARGV[0]; shift;
+  } else {
+    die "Invalid option: $ARGV[0]";
+  }
+  shift;
+}
+
+if (length($srcroot) == 0) {
+  chomp($srcroot = `llvm-config --src-root`);
+}
+if (! -d "$srcroot") {
+  die "Invalid source root: $srcroot\n";
+}
+chdir($srcroot);
+my $llvmdo = "$srcroot/utils/llvmdo -topdir '$srcroot'";
+my %Stats;
+my %FileStats;
+
+my $annotate = "cvs -z6 annotate -lf ";
+if (length($tag) > 0)
+{
+  $annotate = $annotate . " -r" . $tag;
+}
+
+sub GetCVSFiles
+{
+  my $d = $_[0];
+  my $files ="";
+  open FILELIST, 
+    "$llvmdo -dirs \"$d\" -code-only echo |" || die "Can't get list of files with llvmdo";
+  while ( defined($line = <FILELIST>) ) {
+    chomp($file = $line);
+    print "File: $file\n" if ($debug);
+    $files = "$files $file";
+  }
+  return $files;
+}
+
+sub ScanDir
+{
+  my $Dir = $_[0];
+  my $files = GetCVSFiles($Dir);
+
+  open (DATA,"$annotate $files 2>&1 |")
+    || die "Can't read cvs annotation data";
+
+  my $curfile = "";
+  while ( defined($line = <DATA>) )
+  {
+    chomp($line);
+    if ($line =~ '^Annotations for.*') {
+      $curfile = $line;
+      $curfile =~ s#^Annotations for ([[:print:]]*)#$1#;
+      print "Scanning: $curfile\n" if ($debug);
+    } elsif ($line =~ /^[0-9.]*[ \t]*\([^)]*\):/) {
+      $uname = $line;
+      $uname =~ s#^[0-9.]*[ \t]*\(([a-zA-Z0-9_.-]*) [^)]*\):.*#$1#;
+      $Stats{$uname}++;
+      if ($filedetails) {
+        $FileStats{$uname} = {} unless exists $FileStats{$uname};
+        ${$FileStats{$uname}}{$curfile}++;
+      }
+    }
+  }
+  close DATA;
+}
+
+sub printStats
+{
+  my $dir = $_[0];
+  my $hash = $_[1];
+  my $user;
+  my $total = 0;
+
+  foreach $user (keys %Stats) { $total += $Stats{$user}; }
+
+  if ($html) { 
+    print "<p>Total Source Lines: $total<br/></p>\n";
+    print "<table>";
+    print " <tr><th style=\"text-align:right\">LOC</th>\n";
+    print " <th style=\"text-align:right\">\%LOC</th>\n";
+    print " <th style=\"text-align:left\">User</th>\n";
+    print "</tr>\n";
+  }
+
+  foreach $user ( sort keys %Stats )
+  {
+    my $v = $Stats{$user};
+    if (defined($v))
+    {
+      if ($html) {
+        printf "<tr><td style=\"text-align:right\">%d</td><td style=\"text-align:right\">(%4.1f%%)</td><td style=\"text-align:left\">", $v, (100.0/$total)*$v;
+        if ($filedetails) {
+          print "<a href=\"#$user\">$user</a></td></tr>";
+        } else {
+          print $user,"</td></tr>";
+        }
+      } else {
+        printf "%8d  (%4.1f%%)  %s\n", $v, (100.0/$total)*$v, $user;
+      }
+    }
+  }
+  print "</table>\n" if ($html);
+
+  if ($filedetails) {
+    foreach $user (sort keys %FileStats) {
+      my $total = 0;
+      foreach $file (sort keys %{$FileStats{$user}}) { 
+        $total += ${$FileStats{$user}}{$file}
+      }
+      if ($html) {
+        print "<table><tr><th style=\"text-align:left\" colspan=\"3\"><a name=\"$user\">$user</a></th></tr>\n";
+      } else {
+        print $user,":\n";
+      }
+      foreach $file (sort keys %{$FileStats{$user}}) {
+        my $v = ${$FileStats{$user}}{$file};
+        if ($html) { 
+          printf "<tr><td style=\"text-align:right\">&nbsp;&nbsp;%d</td><td
+          style=\"text-align:right\">&nbsp;%4.1f%%</td><td
+          style=\"text-align:left\">%s</td></tr>",$v, (100.0/$total)*$v,$file;
+        } else {
+          printf "%8d  (%4.1f%%)  %s\n", $v, (100.0/$total)*$v, $file;
+        }
+      }
+      if ($html) { print "</table>\n"; }
+    }
+  }
+}
+
+
+if ($html)
+{
+print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n";
+print "<html>\n<head>\n";
+print "  <title>LLVM LOC Based On CVS Annotation</title>\n";
+print "  <link rel=\"stylesheet\" href=\"llvm.css\" type=\"text/css\"/>\n";
+print "</head>\n";
+print "<body><div class=\"doc_title\">LLVM LOC Based On CVS Annotation</div>\n";
+print "<p>This document shows the total lines of code per user in each\n";
+print "LLVM directory. Lines of code are attributed by the user that last\n";
+print "committed the line. This does not necessarily reflect authorship.</p>\n";
+}
+
+my @DIRS;
+if ($#ARGV > 0) {
+  @DIRS = @ARGV;
+} else {
+  push @DIRS, 'include';
+  push @DIRS, 'lib';
+  push @DIRS, 'tools';
+  push @DIRS, 'runtime';
+  push @DIRS, 'docs';
+  push @DIRS, 'test';
+  push @DIRS, 'utils';
+  push @DIRS, 'examples';
+  push @DIRS, 'projects/Stacker';
+  push @DIRS, 'projects/sample';
+  push @DIRS, 'autoconf';
+}
+  
+for $Index ( 0 .. $#DIRS) { 
+  print "Scanning Dir: $DIRS[$Index]\n" if ($debug);
+  ScanDir($DIRS[$Index]); 
+}
+
+printStats;
+
+print "</body></html>\n" if ($html) ;
diff --git a/src/LLVM/utils/valgrind/x86_64-pc-linux-gnu_gcc-4.3.3.supp b/src/LLVM/utils/valgrind/x86_64-pc-linux-gnu_gcc-4.3.3.supp
new file mode 100644
index 0000000..a86be6c
--- /dev/null
+++ b/src/LLVM/utils/valgrind/x86_64-pc-linux-gnu_gcc-4.3.3.supp
@@ -0,0 +1,23 @@
+{
+   libstdcxx_overlapped_memcpy_in_stable_sort_1
+   Memcheck:Overlap
+   fun:memcpy
+   ...
+   fun:_ZSt11stable_sortIN9__gnu_cxx17__normal_iteratorIPSt4pairIPKN4llvm5ValueEjESt6vectorIS7_SaIS7_EEEEN12_GLOBAL__N_116CstSortPredicateEEvT_SF_T0_
+}
+
+{
+   libstdcxx_overlapped_memcpy_in_stable_sort_2
+   Memcheck:Overlap
+   fun:memcpy
+   ...
+   fun:_ZSt11stable_sortIN9__gnu_cxx17__normal_iteratorIPSt4pairIPKN4llvm5ValueEjESt6vectorIS7_SaIS7_EEEEN12_GLOBAL__N_116CstSortPredicateEEvT_SF_T0_
+}
+
+{
+   libstdcxx_overlapped_memcpy_in_stable_sort_3
+   Memcheck:Overlap
+   fun:memcpy
+   ...
+   fun:_ZSt11stable_sortIN9__gnu_cxx17__normal_iteratorIPSt4pairIPKN4llvm4TypeEjESt6vectorIS7_SaIS7_EEEEPFbRKS7_SE_EEvT_SH_T0_
+}
diff --git a/src/LLVM/utils/vim/README b/src/LLVM/utils/vim/README
new file mode 100644
index 0000000..8a31abf
--- /dev/null
+++ b/src/LLVM/utils/vim/README
@@ -0,0 +1,43 @@
+-*- llvm/utils/vim/README -*-

+

+These are syntax highlighting files for the VIM editor. Included are:

+

+* llvm.vim

+

+  Syntax highlighting mode for LLVM assembly files. To use, copy `llvm.vim' to

+  ~/.vim/syntax and add this code to your ~/.vimrc :

+

+  augroup filetype

+    au! BufRead,BufNewFile *.ll     set filetype=llvm

+  augroup END

+

+* tablegen.vim

+

+  Syntax highlighting mode for TableGen description files. To use, copy

+  `tablegen.vim' to ~/.vim/syntax and add this code to your ~/.vimrc :

+

+  augroup filetype

+    au! BufRead,BufNewFile *.td     set filetype=tablegen

+  augroup END

+

+

+If you prefer, instead of making copies you can make symlinks from

+~/.vim/syntax/... to the syntax files in your LLVM source tree. Apparently

+this did not work with older versions of vim however, so if this doesn't

+work you may need to make actual copies of the files.

+

+Another option, if you do not already have a ~/.vim/syntax directory, is

+to symlink ~/.vim/syntax itself to llvm/utils/vim .

+

+Note: If you notice missing or incorrect syntax highlighting, please contact

+<llvmbugs [at] cs.uiuc.edu>; if you wish to provide a patch to improve the

+functionality, it will be most appreciated. Thank you.

+

+If you find yourself working with LLVM Makefiles often, but you don't get syntax

+highlighting (because the files have names such as Makefile.rules or

+TEST.nightly.Makefile), add the following to your ~/.vimrc:

+

+  " LLVM Makefile highlighting mode

+  augroup filetype

+    au! BufRead,BufNewFile *Makefile*     set filetype=make

+  augroup END

diff --git a/src/LLVM/utils/vim/llvm.vim b/src/LLVM/utils/vim/llvm.vim
new file mode 100644
index 0000000..66419ec
--- /dev/null
+++ b/src/LLVM/utils/vim/llvm.vim
@@ -0,0 +1,111 @@
+" Vim syntax file

+" Language:   llvm

+" Maintainer: The LLVM team, http://llvm.org/

+" Version:      $Revision: 109772 $

+

+if version < 600

+  syntax clear

+elseif exists("b:current_syntax")

+  finish

+endif

+

+syn case match

+

+" Types.

+" Types also include struct, array, vector, etc. but these don't

+" benefit as much from having dedicated highlighting rules.

+syn keyword llvmType void float double

+syn keyword llvmType x86_fp80 fp128 ppc_fp128

+syn keyword llvmType type label opaque

+syn match   llvmType /\<i\d\+\>/

+

+" Instructions.

+" The true and false tokens can be used for comparison opcodes, but it's

+" much more common for these tokens to be used for boolean constants.

+syn keyword llvmStatement add fadd sub fsub mul fmul

+syn keyword llvmStatement sdiv udiv fdiv srem urem frem

+syn keyword llvmStatement and or xor

+syn keyword llvmStatement icmp fcmp

+syn keyword llvmStatement eq ne ugt uge ult ule sgt sge slt sle

+syn keyword llvmStatement oeq ogt oge olt ole one ord ueq ugt uge

+syn keyword llvmStatement ult ule une uno

+syn keyword llvmStatement nuw nsw exact inbounds

+syn keyword llvmStatement phi call select shl lshr ashr va_arg

+syn keyword llvmStatement trunc zext sext

+syn keyword llvmStatement fptrunc fpext fptoui fptosi uitofp sitofp

+syn keyword llvmStatement ptrtoint inttoptr bitcast

+syn keyword llvmStatement ret br indirectbr switch invoke unwind unreachable

+syn keyword llvmStatement malloc alloca free load store getelementptr

+syn keyword llvmStatement extractelement insertelement shufflevector

+syn keyword llvmStatement extractvalue insertvalue

+

+" Keywords.

+syn keyword llvmKeyword define declare global constant

+syn keyword llvmKeyword internal external private

+syn keyword llvmKeyword linkonce linkonce_odr weak weak_odr appending

+syn keyword llvmKeyword common extern_weak

+syn keyword llvmKeyword thread_local dllimport dllexport

+syn keyword llvmKeyword hidden protected default

+syn keyword llvmKeyword except deplibs

+syn keyword llvmKeyword volatile fastcc coldcc cc ccc

+syn keyword llvmKeyword x86_stdcallcc x86_fastcallcc

+syn keyword llvmKeyword signext zeroext inreg sret nounwind noreturn

+syn keyword llvmKeyword nocapture byval nest readnone readonly noalias

+syn keyword llvmKeyword inlinehint noinline alwaysinline optsize ssp sspreq

+syn keyword llvmKeyword noredzone noimplicitfloat naked alignstack

+syn keyword llvmKeyword module asm align tail to

+syn keyword llvmKeyword addrspace section alias sideeffect c gc

+syn keyword llvmKeyword target datalayout triple

+syn keyword llvmKeyword blockaddress

+syn keyword llvmKeyword union

+

+" Obsolete keywords.

+syn keyword llvmError  uninitialized implementation

+syn keyword llvmError  getresult big little endian begin end

+

+" Misc syntax.

+syn match   llvmNoName /[%@]\d\+\>/

+syn match   llvmNumber /-\?\<\d\+\>/

+syn match   llvmFloat  /-\?\<\d\+\.\d*\(e[+-]\d\+\)\?\>/

+syn match   llvmFloat  /\<0x\x\+\>/

+syn keyword llvmBoolean true false

+syn keyword llvmConstant zeroinitializer undef null

+syn match   llvmComment /;.*$/

+syn region  llvmString start=/"/ skip=/\\"/ end=/"/

+syn match   llvmLabel /[-a-zA-Z$._][-a-zA-Z$._0-9]*:/

+syn match   llvmIdentifier /[%@][-a-zA-Z$._][-a-zA-Z$._0-9]*/

+

+" Syntax-highlight dejagnu test commands.

+syn match  llvmSpecialComment /;\s*RUN:.*$/

+syn match  llvmSpecialComment /;\s*PR\d*\s*$/

+syn match  llvmSpecialComment /;\s*END\.\s*$/

+syn match  llvmSpecialComment /;\s*XFAIL:.*$/

+syn match  llvmSpecialComment /;\s*XTARGET:.*$/

+

+if version >= 508 || !exists("did_c_syn_inits")

+  if version < 508

+    let did_c_syn_inits = 1

+    command -nargs=+ HiLink hi link <args>

+  else

+    command -nargs=+ HiLink hi def link <args>

+  endif

+

+  HiLink llvmType Type

+  HiLink llvmStatement Statement

+  HiLink llvmNumber Number

+  HiLink llvmComment Comment

+  HiLink llvmString String

+  HiLink llvmLabel Label

+  HiLink llvmKeyword Keyword

+  HiLink llvmBoolean Boolean

+  HiLink llvmFloat Float

+  HiLink llvmNoName Identifier

+  HiLink llvmConstant Constant

+  HiLink llvmSpecialComment SpecialComment

+  HiLink llvmError Error

+  HiLink llvmIdentifier Identifier

+

+  delcommand HiLink

+endif

+

+let b:current_syntax = "llvm"

diff --git a/src/LLVM/utils/vim/tablegen.vim b/src/LLVM/utils/vim/tablegen.vim
new file mode 100644
index 0000000..ffd4ea8
--- /dev/null
+++ b/src/LLVM/utils/vim/tablegen.vim
@@ -0,0 +1,54 @@
+" Vim syntax file

+" Language:   TableGen

+" Maintainer: The LLVM team, http://llvm.org/

+" Version:    $Revision: 97271 $

+

+if version < 600

+  syntax clear

+elseif exists("b:current_syntax")

+  finish

+endif

+

+" May be changed if you have a really slow machine

+syntax sync minlines=100

+

+syn case match

+

+syn keyword tgKeyword   def let in code dag field include defm

+syn keyword tgType      class int string list bit bits multiclass

+

+syn match   tgNumber    /\<\d\+\>/

+syn match   tgNumber    /\<\d\+\.\d*\>/

+syn match   tgNumber    /\<0b[01]\+\>/

+syn match   tgNumber    /\<0x[0-9a-fA-F]\+\>/

+syn region  tgString    start=/"/ skip=/\\"/ end=/"/    oneline

+

+syn region  tgCode      start=/\[{/ end=/}\]/

+

+syn keyword tgTodo             contained TODO FIXME

+syn match   tgComment   /\/\/.*$/         contains=tgTodo

+" Handle correctly imbricated comment

+syn region  tgComment2 matchgroup=tgComment2  start=+/\*+ end=+\*/+ contains=tgTodo,tgComment2

+

+if version >= 508 || !exists("did_c_syn_inits")

+  if version < 508

+    let did_c_syn_inits = 1

+    command -nargs=+ HiLink hi link <args>

+  else

+    command -nargs=+ HiLink hi def link <args>

+  endif

+

+  HiLink tgKeyword Statement

+  HiLink tgType Type

+  HiLink tgNumber Number

+  HiLink tgComment Comment

+  HiLink tgComment2 Comment

+  HiLink tgString String

+  " May find a better Hilight group...

+  HiLink tgCode Special

+  HiLink tgTodo Todo

+

+  delcommand HiLink

+endif

+

+let b:current_syntax = "tablegen"

diff --git a/src/LLVM/utils/vim/vimrc b/src/LLVM/utils/vim/vimrc
new file mode 100644
index 0000000..a48a068
--- /dev/null
+++ b/src/LLVM/utils/vim/vimrc
@@ -0,0 +1,93 @@
+" LLVM coding guidelines conformance for VIM

+" $Revision: 97273 $

+"

+" Maintainer: The LLVM Team, http://llvm.org

+" WARNING:    Read before you source in all these commands and macros!  Some

+"             of them may change VIM behavior that you depend on.

+"

+" You can run VIM with these settings without changing your current setup with:

+" $ vim -u /path/to/llvm/utils/vim/vimrc

+

+" It's VIM, not VI

+set nocompatible

+

+" A tab produces a 2-space indentation

+set softtabstop=2

+set shiftwidth=2

+set expandtab

+

+" Highlight trailing whitespace and lines longer than 80 columns.

+highlight LongLine ctermbg=DarkYellow guibg=DarkYellow

+highlight WhitespaceEOL ctermbg=DarkYellow guibg=DarkYellow

+if v:version >= 702

+  " Lines longer than 80 columns.

+  au BufWinEnter * let w:m0=matchadd('LongLine', '\%>80v.\+', -1)

+

+  " Whitespace at the end of a line. This little dance suppresses

+  " whitespace that has just been typed.

+  au BufWinEnter * let w:m1=matchadd('WhitespaceEOL', '\s\+$', -1)

+  au InsertEnter * call matchdelete(w:m1)

+  au InsertEnter * let w:m2=matchadd('WhitespaceEOL', '\s\+\%#\@<!$', -1)

+  au InsertLeave * call matchdelete(w:m2)

+  au InsertLeave * let w:m1=matchadd('WhitespaceEOL', '\s\+$', -1)

+else

+  au BufRead,BufNewFile * syntax match LongLine /\%>80v.\+/

+  au InsertEnter * syntax match WhitespaceEOL /\s\+\%#\@<!$/

+  au InsertLeave * syntax match WhitespaceEOL /\s\+$/

+endif

+

+" Enable filetype detection

+filetype on

+

+" Optional

+" C/C++ programming helpers

+augroup csrc

+  au!

+  autocmd FileType *      set nocindent smartindent

+  autocmd FileType c,cpp  set cindent

+augroup END

+" Set a few indentation parameters. See the VIM help for cinoptions-values for

+" details.  These aren't absolute rules; they're just an approximation of

+" common style in LLVM source.

+set cinoptions=:0,g0,(0,Ws,l1

+" Add and delete spaces in increments of `shiftwidth' for tabs

+set smarttab

+

+" Highlight syntax in programming languages

+syntax on

+

+" LLVM Makefiles can have names such as Makefile.rules or TEST.nightly.Makefile,

+" so it's important to categorize them as such.

+augroup filetype

+  au! BufRead,BufNewFile *Makefile* set filetype=make

+augroup END

+

+" In Makefiles, don't expand tabs to spaces, since we need the actual tabs

+autocmd FileType make set noexpandtab

+

+" Useful macros for cleaning up code to conform to LLVM coding guidelines

+

+" Delete trailing whitespace and tabs at the end of each line

+command! DeleteTrailingWs :%s/\s\+$//

+

+" Convert all tab characters to two spaces

+command! Untab :%s/\t/  /g

+

+" Enable syntax highlighting for LLVM files. To use, copy

+" utils/vim/llvm.vim to ~/.vim/syntax .

+augroup filetype

+  au! BufRead,BufNewFile *.ll     set filetype=llvm

+augroup END

+

+" Enable syntax highlighting for tablegen files. To use, copy

+" utils/vim/tablegen.vim to ~/.vim/syntax .

+augroup filetype

+  au! BufRead,BufNewFile *.td     set filetype=tablegen

+augroup END

+

+" Additional vim features to optionally uncomment.

+"set showcmd

+"set showmatch

+"set showmode

+"set incsearch

+"set ruler

diff --git a/src/LLVM/utils/webNLT.pl b/src/LLVM/utils/webNLT.pl
new file mode 100644
index 0000000..fb29fd2
--- /dev/null
+++ b/src/LLVM/utils/webNLT.pl
@@ -0,0 +1,83 @@
+#!/usr/bin/perl
+
+use DBI;
+use CGI;
+
+$q = new CGI;
+print $q->header();
+print $q->start_html(-title=>"Nightly Tester DB");
+
+unless($q->param('pwd'))
+  {
+    print $q->startform();
+    print $q->password_field(-name=>"pwd", -size=>20, -maxlength=>20);
+    print $q->submit();
+    print $q->endform();
+  }
+else
+  {
+    # database information
+    $db="llvmalpha";
+    $host="localhost";
+    $userid="llvmdbuser";
+    $passwd=$q->param('pwd');
+    $connectionInfo="dbi:mysql:$db;$host";
+    
+    # make connection to database
+    $dbh = DBI->connect($connectionInfo,$userid,$passwd) or die DBI->errstr;
+    $query = "Select DISTINCT(NAME) from Tests";
+    my $sth = $dbh->prepare($query) || die "Can't prepare statement: $DBI::errstr";
+    my $rc = $sth->execute or die DBI->errstr;
+    while (($n) = $sth->fetchrow_array)
+      {
+        push @names, ($n);
+#        print "$n<P>";
+      }
+    $query = "Select DISTINCT(TEST) from Tests";
+    my $sth = $dbh->prepare($query) || die "Can't prepare statement: $DBI::errstr";
+    my $rc = $sth->execute or die DBI->errstr;
+    while (($n) = $sth->fetchrow_array)
+      {
+        push @tests, ($n);
+#        print "$n\n";
+      }
+
+#    print join "<BR>", @names;
+
+    print $q->startform();
+    print $q->scrolling_list(-name=>"test", -values=>\@tests, -multiple=>'true');
+    print "<P>";
+    print $q->scrolling_list(-name=>"name", -values=>\@names, -multiple=>'true');
+    print "<P>";
+    print $q->submit();
+    print $q->hidden("pwd", $q->param('pwd'));
+    print $q->endform();
+
+    # disconnect from database
+    $dbh->disconnect;
+
+    #now generate the urls to the chart
+    if ($q->param('test') && $q->param('name'))
+      {
+        my @names = $q->param('name');
+        my @tests = $q->param('test');
+        print "<P>";
+        print join "<BR>", @names;
+        print "<P>";
+        print join "<BR>", @tests;
+        print "<P>";
+        $str = "pwd=" . $q->param('pwd');
+        $count = 0;
+        foreach $n (@names)
+          {
+            foreach $t (@tests)
+              {
+                $str = "$str&t$count=$t&n$count=$n";
+                $count++;
+              }
+          }
+        print "<img src=\"cgiplotNLT.pl?$str\">";
+      }
+  }
+
+print $q->end_html();